/arch/sparc/boot/

ss='main'>index : litmus-rt.git
The LITMUS^RT kernel.Bjoern Brandenburg
aboutsummaryrefslogblamecommitdiffstats
path: root/drivers/media/usb/dvb-usb/dib0700_devices.c
blob: 829323e42ca095671372ec15de5cea81a4810fea (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11





                                                                                  
                                         



                      
                     
                     
                    
                    
                   
                   
                         
                   
                   
                    
                    
                    

                     
 




                                                                                               
                              
                                                      
                                                 


                                     



                                                        
                                 




                                    
 

                                                                       
                                                                                     
 



                          
 

                       
 

                          

                      
                       
 

                           
















                                                                    
                                                   





                                                                             



                                                                        
 




                                                                                                                                      
                                        
                                                                                        
                                                                                                  

 
                                                                 








                                                                            

                                                             
                                                            
                                                                                             

                     

                                                                                                       

                                                                          


                                                                          

 
                                                                
 


                                                                        
                         


                                                                                                                      


































                                                                                   
            
                                      


                                                                                                                      


































                                                                                   
         


                                                                     





                                           






                                                                   

                                                        

                                                   


                                                              




                                               

                                                        

                                                   


                                                              









                                                         











                                                                  





                                                                                                 

         



                                                                       
 
                                                         

 












                                                                 





                                                                                                 

         



                                                                       
 
                                                         




                                                              

                                                                                               
                                                                         

 
                                                                     
                                                      









































                                                                             
                                                           






















                                                                                

                                                              





                                                         

                                                                            


















                                                                 






                                                                          

                                                                               













                                                         





                                                                              
 
                                                                                     

                                                  
                                                         





                                                               
                                                              


                                                   

                                                     
                                                                  
 
                                                                                       


                                      
                              


                                                
                                                           
                         
 





                                                                       

                  

                    
              
                                           
 







                                                                            

                                                      
                                       
                          
         

                                                                     

                                                                     




                                                                                                                          
                          
                                            
                        

                                                                




                                                           
                 
 
                                                  
                      
                
                                                                      

                                                   
                                                       
 

                      


                 
                                                       
                                                                     
                            


                                                                                                              





































                                                                           


          




                                                                                                              

                                                                           
 

            
 

            
 



             
 



              
 


            
 

            
 

          
 

           
 

           
 

           
 
          


                                                              






                                           







                                                          










                                                          
                              

                                                 



                                                      



                                                                 
                                                   
                                                                                            



                                                                     
                                                                     

                                                         
                                                                     



                                                                      
 
                                 

                                                        
                                                                                                                       

                                     
                                                                                                                       
 
                                                         

 



                                                      

                                                              
                                                            
                                                   
                                    

                     

                                                                                                       

                                                               
                             
                                                                                                       
            
                                                                                                       
 
                                                                                               
                                           

 




                                                                                                              



































                                                                           



                                                                  
                                     




                                                                  
                                     








                                                           

                                     




                                                           
                                 


         






                                                        
                          

  
                                                              
 
                                                                    



                                                         
                                                       






                                                                            
                                         

 
                                                              
 


                                                                    

                    
                                                        












                                                                             
                                          




                                                              
                                                                                   

                                                         
                                                                     
                                                          

                                

                                                                                    


                  


                                                              
                                                                                                                   

                            
                                                                                                                  

                                       
                                                                                                                  


                                       

                                                                                   


                 




                                                                          

                                                                                      





                                                                               

                                                                               

 

                                                                                              
                                                                              



                                                                               
                                                                       

 
                                                                   






                                           







                                                          

                               










                                                                 



                                                                       
            
                                                                












                                                         





                                                                              
 
                                                                                     
                                           
                                                         

 















                                                          
                                     





























                                                                              
                                                                                     
                                           
                                                         

 












































































































































                                                                               
                                                                  



                                                  
                                                                  











                                                                   

                                             











                                                           

                                             












                                                 
                                                              
 
                                                                    



                                                         
                                                       










                                                  
                                         




                                                             
                                                                                 


                                                        
                                                                            


                                                                    
                                                                            



                                                                    

                                                                                   


                 

                                                                         
 
                                                                             

 
                                                                   
                          
 
                                                                      
 



















                                                                
                                         
 
                                                                                    

                                                          
                                                          






















                                                                    
                                                                        
 
                                                                                    

                                                          
                                                         




                                                                    
                                                                        
 
                                                                                    

                                                          
                                                         

 
               
                                                          
         
                                                      
                                                                          

                                                                             



































                                                                           

          
                   
                                                                          

                                                                             



































                                                                           
         


                                                                   






                                           



                                                         


                                            








                                                                    





                                                          
                                           












                                                     
            



                                       
                                           














































                                                                                       























                                                                                                        
                                                              


                                                         


                                                                                        

                                                          










                                                                                                                                                      
 
                                        


                           

















                                                                                                         
 









                                                                                                                 

                                 

                                                                 
 







                                                                                                  
                                                                                                                                 


                                                                      

                                                   


                                                           
                
                                                                              

                                                                         







                                                             
                                                                                                                  
 
                                                                                                        

                               

                                                                                   



















                                                                
                                                                      
 
                                                                                                                 
 
                                                          





                                                               
                                                                                            




                                                                                                     
                                                         

                                                                                

                                                                                                        

                               

                                                                                   








                                                                  
                   









                                                         
                   
                                                         
                   

                                                        
                                                                      
 

                                                                                                                 


                                                                                                      
                                                                  



                                               











































































































































































                                                                                          



                          

  







































































                                                                                                                                                                                                                                                                                            
                                                        



                                                         
                                     
                   
                
 
                                        









                                                                 


                                                        
 
                                                      
                                                                                            

                                                                





                                                                 






                                                                      






































                                                                                  


                                                                                             
                                                                                



                                                                              
                                                                         
















                                                                         

                                                                            








                                           
               

                                                                                                               
               

                                                       
               

                                                       
                

                                                      
         














                                                                 

                                                     































































































                                                                                                                                                                                              
            































                                                                      
                   






                                                         
                   
                                                         
                   












                                                                                                     
                                                                                                       
 
                                                          




                                                             
                                                                                   







                               
                                                                                                       
                               
                                                                                             

                                                          
                                               
                                                                    
                               
                                                   

















                                                                      
                   






                                                         
                   
                                                         
                   













                                                                                                     
                                                                                                           
 
                                        

                               
                                                                                             


                                                                               
                                                                  

                                               

 











                                                               

                                                                                                            
                               
                                                                                             

                                                         

                                               
                                                                    

                               
                                                                      
                               
                                                                               




                                                                                                         
                                                         
                                                                              


                                                                 
                                                   




                 
                                                                                              

















                                                                                               
                                            



                                
                                              
                             
                                    





                                                                              
                                                                   
                                    

                                                                      



                                                                      
                                                                                                                                   

                                                                         

                                                                                                                                                                                                                                                                                    




                                                                 
                                                    

                                                                           

                                                                                             










                                                                                                                     
                                                          
                               
            


                         
                                                       




                                                         
                                     

                
                                        




                                                                 
                                                          

                                         
                                                        








                                                                 







                                                                   
                                                                       
 
                                                          
 


                                               
                

                                                 




                 
                                                       




                                       

  
                                                          



                                                                                                                      
                                                                                                                                                  
 

                                      
 

                                      
 



                                       
 
                                        
                                        
 

                                        
 








                                      
 



                                     
 
                                           



                                                                                                                      
                                                                                                                                                  
 

                                      
 

                                      
 



                                       
 

                                        
 

                                        
 




                                      
                                     


                                      
 



                                     
 
                                           



                                                                      






                                           





                                                         
                                                                                                                     






















                                                                                               













                                                                           




                                                               
                                                                                          





















                                                                                                       
            


                                                            
                                                                                          


























































                                                                                                       
                                                          


                                                    
                                                                              






















                                                                                               
                                                              
























                                               
                                 




                            

                               


                                
































                                                                   
            




































                                                                
                   




                                                         
                   
                                                         
                   
                                                        
 



                                                                                                     
                                                                                                                
 
                                                          

 
                                                             
 
                                                      
                                                                                 
 
                                                                                                        
                               
 
                                                        
 

                                                                            
                 

 
                                                                    
 




                                                                       
                                                        
                   


                                                        

                                                         
                   
                                                         
                   

                                                        




                                                                                                           
 
                                              

                                                                                                                      

                               
                                                 
 






                                                                    
                                                          



                                                                                
                                                                                                              




                                                                                          
                                                                                                     

                                              
                                                         




                                                                 
                                                                                 
 
                                                                                                              

                               
                                                        
 

                                                                            





                                                                 
                                                                                 
 
                                                                                                              

                               
                                                        
 

                                                                            
                 
 
 
                                                                 


                                                   
                                                                        














                                                          
                                                                           




                                                                               
                                                         



                                                          
                                                              





                                                                      
                                                                  








                                                                            







                                                              

                                       











                                                              

                                       








                                                              
                                                      
 
                                                  
                   



                                                   
 
                                       

                   






                                                                   


                                                        





                                                                              
 

                                                                                                                     



                                                                   

                                                                                                                     

 




























                                                                              








                                                                             
                                             



















                                                                                      









                                                                           

 



















































                                                                            
                                                                               
                                                    
                                                         

 

                                                                   


                                            


                                                                
                           
                                                                
                           



                                                                             






                                                          



                                                            
                                                     
                                                                      
 
                                                                                   
                                                      


                                      






                                                                   
                                                                
                           
                                                                







                                                                             























                                                                     
                           





                                      
                                                                     







                                                                            

  

                                                   
                                       

                              
                                                 
                                           
 







































                                                                          

                    




                                                             
                                                                                     


                                                 
                                                         

 
                                                           




                                 



                                                            


                                                   
                                                              

                                                                          
                                                                   



                                      
                                                                      
 
                                                                      
                                                       


                                      


















































                                                                        
                                                         


                                                    
                                                         



                                                              
                                                               




                                                                      
                                   
                                               
                                                                   



                                                                          
                                                                   



                                                                               
                                                                     




                                                                           
                                                                   




                                                                             
                                                                     











                                                                               
                                                                          
                                                                                 
                                                                                 
                                                                          
                                                                  
                                                                  
                                                               
                                                                     
                                                                        
                                                                              

                                                                      
                                                               
                                                               

                                                                             
                                                              
                                                                    
                                                                        
                                                                        

                                                               
                                                                 

                                                                    

                                                                      
                                                                   
                                                                            

                                                                     
                                                                                      
                                                              
                                                                      
                                                                     
                                                                    
                                                                          




                                                                     
                                                                                 
                                                                   
                                                                     
                                                                        


                                                                      

                                                                 
                                               





                                                         
                                                         
                                                         
                                 
                                                            

                                                   




















                                                      

                                           

                                                                                                                

                                                                             



                                                                             
                           


                          
                                      

                                                               
                                                                                       


                                                     
                                                                                             


                                                           
                                                                                        

                                         
                                                    
                                                                                        
                                         



                                                                       

                                                                          
                                                                                        
                                         



                                                              
                          


                                                                    
                         

                  
                            
                                                                
                                                                     
                                                                          


                                                            
                                                                    
                  




                                               

                                           



                                                                            
                           
                            

                                           



                                                                            
                           





                                                              
                                                                                             

                                         

                  
                            
                                                                
                                                                     
                                                                          


                                                            
                                                                   
                  




                                               

                                           



                                                                                                                



                                                                             
                           
                            

                                           



                                                                                                                



                                                                             
                           


                         
                                      








                                                                    
                                                                              


                                                                    
                                                               

                                                                    
                          



                                                                    
 
                  
 
                            
                                                                
                                                                     
                                                                          


                                                            
                                                                   
                  




                                               

                                           



                                                                                                                



                                                                              
                           


                          
                                      




                                                                    


                                                                    



                                                                    
                         

                  
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                   
                  




                                               

                                           



                                                                                                                



                                                                             
                           



                                                                                         
                                       








                                                                    


                                                                    




                                                                    



                                                                    



                                                                    







                                                                    



                                                                    



                                                                    



                                                                    
                                                      
                                                                    

                                         

                  
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  




                                               

                                           



                                                                                                                



                                                                             
                           



                                                                                         
                                      





                                                                    
                                                                                               


                                                 
                                                                                               



                                         
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  




                                               

                                           



                                                                                                                
                                                                           


                                                                          
                           

                                                                                         

                                           



                                                                                                                
                                                                           


                                                                          
                           



                                                                                         
                                      




                                                                    







                                                                    






                                                                          


                                                            



































                                                                                                                







                                                                       
                          


                                                                    
                          


                                                                         
                                         



                                                                    
                          





                                                                     
                                                                          


                                                            
                                                                   





                                               

                                           







                                                                                                                
                           

                                                                                         

                                           







                                                                                                                
                           





                                                                                         



                                                                    
                  
 
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  




                                               

                                           



                                                                                                                



                                                                              
                           




                                                                       
                                      












                                                                    



                                                                    



                                                                    



                                                                    



                                                                    



                                                                    



                                                                    
                  
 
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  



                                               

                                           



                                                                            
                           




                                                                       
                                      




                                                                    



                                                                    
                  

                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  



                                               

                                           



                                                                             
                           















                                                                       




                                               

                                           



                                                                                                                
                                                                             


                                                                          
                           
                                               
                                                                             


                          
                                      




                                                                    



                                                                         

                                         



                                                                    



                                                                    
                  

                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  



                                               

                                           

                                                                                                                 

                                                                           



                                                                            
                           




                                                                             
                                      




                                                                    



                                                                    



                                                                    

                  
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  



                                               

                                           

                                                                                                                 

                                                                           



                                                                                
                           



                                                                             

                                           

                                                                                                                 

                                                                           



                                                                                
                           












                                                                             
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  



                                               

                                           








                                                                                  
                           












                                                                             
                            
                                                                
                                                                     
                                                      
                                                                          


                                                            
                                                                    
                  



                                               

                                           








                                                                                  
                           

















                                                                             


                                                            





                                                                    

                                           








                                                                                  
                           

















                                                                             


                                                            





                                                                    

                                           








                                                                                  
                           

















                                                                             


                                                            





                                                                    

                                           








                                                                                  
                           

















                                                                             


                                                            





                                                                    

                                           








                                                                                  
                           



                                                                             

                                           








                                                                                  
                           

















                                                                             


                                                            

                                                                    



                                               

                                           
                                                                             


                                                                        
                           




                                                                       
                                      




                                                                    



                                                                    





                                                                          


                                                            

                                                                    










                                                                                          

                                                                                     










                                                                               

                                                                    








                                                                          


                                                            

                                                                    

























                                                                                          
                                                                    








                                                                          


                                                            

                                                                    
          


                                                       
/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
 *
 *	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, version 2.
 *
 *  Copyright (C) 2005-9 DiBcom, SA et al
 */
#include "dib0700.h"

#include "dib3000mc.h"
#include "dib7000m.h"
#include "dib7000p.h"
#include "dib8000.h"
#include "dib9000.h"
#include "mt2060.h"
#include "mt2266.h"
#include "tuner-xc2028.h"
#include "xc5000.h"
#include "xc4000.h"
#include "s5h1411.h"
#include "dib0070.h"
#include "dib0090.h"
#include "lgdt3305.h"
#include "mxl5007t.h"

static int force_lna_activation;
module_param(force_lna_activation, int, 0644);
MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
		"if applicable for the device (default: 0=automatic/off).");

struct dib0700_adapter_state {
	int (*set_param_save) (struct dvb_frontend *);
	const struct firmware *frontend_firmware;
};

/* Hauppauge Nova-T 500 (aka Bristol)
 *  has a LNA on GPIO0 which is enabled by setting 1 */
static struct mt2060_config bristol_mt2060_config[2] = {
	{
		.i2c_address = 0x60,
		.clock_out   = 3,
	}, {
		.i2c_address = 0x61,
	}
};


static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
	.band_caps = BAND_VHF | BAND_UHF,
	.setup     = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),

	.agc1_max = 42598,
	.agc1_min = 17694,
	.agc2_max = 45875,
	.agc2_min = 0,

	.agc1_pt1 = 0,
	.agc1_pt2 = 59,

	.agc1_slope1 = 0,
	.agc1_slope2 = 69,

	.agc2_pt1 = 0,
	.agc2_pt2 = 59,

	.agc2_slope1 = 111,
	.agc2_slope2 = 28,
};

static struct dib3000mc_config bristol_dib3000mc_config[2] = {
	{	.agc          = &bristol_dib3000p_mt2060_agc_config,
		.max_time     = 0x196,
		.ln_adc_level = 0x1cc7,
		.output_mpeg2_in_188_bytes = 1,
	},
	{	.agc          = &bristol_dib3000p_mt2060_agc_config,
		.max_time     = 0x196,
		.ln_adc_level = 0x1cc7,
		.output_mpeg2_in_188_bytes = 1,
	}
};

static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct dib0700_state *st = adap->dev->priv;
	if (adap->id == 0) {
		dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(10);
		dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);

		if (force_lna_activation)
			dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
		else
			dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);

		if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
			dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
			return -ENODEV;
		}
	}
	st->mt2060_if1[adap->id] = 1220;
	return (adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
		(10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
}

static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
{
	struct i2c_msg msg[2] = {
		{ .addr = 0x50, .flags = 0,        .buf = &adrs, .len = 1 },
		{ .addr = 0x50, .flags = I2C_M_RD, .buf = pval,  .len = 1 },
	};
	if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
	return 0;
}

static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
	struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
	s8 a;
	int if1=1220;
	if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
		adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
		if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
	}
	return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c,
			  &bristol_mt2060_config[adap->id], if1) == NULL ?
			  -ENODEV : 0;
}

/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */

/* MT226x */
static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
	{
		BAND_UHF,

		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
		* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
		(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
	    | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),

		1130,
		21,

		0,
		118,

		0,
		3530,
		1,
		0,

		65535,
		33770,
		65535,
		23592,

		0,
		62,
		255,
		64,
		64,
		132,
		192,
		80,
		80,

		17,
		27,
		23,
		51,

		1,
	}, {
		BAND_VHF | BAND_LBAND,

		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
		* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
		(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
	    | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),

		2372,
		21,

		0,
		118,

		0,
		3530,
		1,
		0,

		65535,
		0,
		65535,
		23592,

		0,
		128,
		128,
		128,
		0,
		128,
		253,
		81,
		0,

		17,
		27,
		23,
		51,

		1,
	}
};

static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
	60000, 30000,
	1, 8, 3, 1, 0,
	0, 0, 1, 1, 2,
	(3 << 14) | (1 << 12) | (524 << 0),
	0,
	20452225,
};

static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
	{	.output_mpeg2_in_188_bytes = 1,
		.hostbus_diversity = 1,
		.tuner_is_baseband = 1,

		.agc_config_count = 2,
		.agc = stk7700d_7000p_mt2266_agc_config,
		.bw  = &stk7700d_mt2266_pll_config,

		.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
		.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
		.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
	},
	{	.output_mpeg2_in_188_bytes = 1,
		.hostbus_diversity = 1,
		.tuner_is_baseband = 1,

		.agc_config_count = 2,
		.agc = stk7700d_7000p_mt2266_agc_config,
		.bw  = &stk7700d_mt2266_pll_config,

		.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
		.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
		.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
	}
};

static struct mt2266_config stk7700d_mt2266_config[2] = {
	{	.i2c_address = 0x60
	},
	{	.i2c_address = 0x60
	}
};

static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
{
	if (adap->id == 0) {
		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
		msleep(10);
		dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
		dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
		dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
		msleep(10);
		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
		msleep(10);
		if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
					     stk7700d_dib7000p_mt2266_config)
		    != 0) {
			err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
			return -ENODEV;
		}
	}

	adap->fe_adap[0].fe =
		dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
			   0x80 + (adap->id << 1),
			   &stk7700d_dib7000p_mt2266_config[adap->id]);

	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
{
	if (adap->id == 0) {
		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
		msleep(10);
		dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
		dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
		dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
		msleep(10);
		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
		msleep(10);
		dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
		if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
					     stk7700d_dib7000p_mt2266_config)
		    != 0) {
			err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
			return -ENODEV;
		}
	}

	adap->fe_adap[0].fe =
		dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
			   0x80 + (adap->id << 1),
			   &stk7700d_dib7000p_mt2266_config[adap->id]);

	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct i2c_adapter *tun_i2c;
	tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
	return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c,
		&stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
}

/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
static struct dibx000_agc_config xc3028_agc_config = {
	BAND_VHF | BAND_UHF,       /* band_caps */

	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
	 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
	 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
	(0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
	(3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */

	712,	/* inv_gain */
	21,	/* time_stabiliz */

	0,	/* alpha_level */
	118,	/* thlock */

	0,	/* wbd_inv */
	2867,	/* wbd_ref */
	0,	/* wbd_sel */
	2,	/* wbd_alpha */

	0,	/* agc1_max */
	0,	/* agc1_min */
	39718,	/* agc2_max */
	9930,	/* agc2_min */
	0,	/* agc1_pt1 */
	0,	/* agc1_pt2 */
	0,	/* agc1_pt3 */
	0,	/* agc1_slope1 */
	0,	/* agc1_slope2 */
	0,	/* agc2_pt1 */
	128,	/* agc2_pt2 */
	29,	/* agc2_slope1 */
	29,	/* agc2_slope2 */

	17,	/* alpha_mant */
	27,	/* alpha_exp */
	23,	/* beta_mant */
	51,	/* beta_exp */

	1,	/* perform_agc_softsplit */
};

/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
static struct dibx000_bandwidth_config xc3028_bw_config = {
	60000, 30000, /* internal, sampling */
	1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
	0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
			  modulo */
	(3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
	(1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
	20452225, /* timf */
	30000000, /* xtal_hz */
};

static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
	.output_mpeg2_in_188_bytes = 1,
	.tuner_is_baseband = 1,

	.agc_config_count = 1,
	.agc = &xc3028_agc_config,
	.bw  = &xc3028_bw_config,

	.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
};

static int stk7700ph_xc3028_callback(void *ptr, int component,
				     int command, int arg)
{
	struct dvb_usb_adapter *adap = ptr;

	switch (command) {
	case XC2028_TUNER_RESET:
		/* Send the tuner in then out of reset */
		dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10);
		dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
		break;
	case XC2028_RESET_CLK:
		break;
	default:
		err("%s: unknown command %d, arg %d\n", __func__,
			command, arg);
		return -EINVAL;
	}
	return 0;
}

static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
	.fname = XC2028_DEFAULT_FIRMWARE,
	.max_len = 64,
	.demod = XC3028_FE_DIBCOM52,
};

static struct xc2028_config stk7700ph_xc3028_config = {
	.i2c_addr = 0x61,
	.ctrl = &stk7700ph_xc3028_ctrl,
};

static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;

	if (desc->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
	    desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
	else
	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
	msleep(20);
	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
	msleep(20);
	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
	msleep(10);

	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
				     &stk7700ph_dib7700_xc3028_config) != 0) {
		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
		    __func__);
		return -ENODEV;
	}

	adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
		&stk7700ph_dib7700_xc3028_config);

	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct i2c_adapter *tun_i2c;

	tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
		DIBX000_I2C_INTERFACE_TUNER, 1);

	stk7700ph_xc3028_config.i2c_adap = tun_i2c;

	/* FIXME: generalize & move to common area */
	adap->fe_adap[0].fe->callback = stk7700ph_xc3028_callback;

	return dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &stk7700ph_xc3028_config)
		== NULL ? -ENODEV : 0;
}

#define DEFAULT_RC_INTERVAL 50

static u8 rc_request[] = { REQUEST_POLL_RC, 0 };

/* Number of keypresses to ignore before start repeating */
#define RC_REPEAT_DELAY 6

/*
 * This function is used only when firmware is < 1.20 version. Newer
 * firmwares use bulk mode, with functions implemented at dib0700_core,
 * at dib0700_rc_urb_completion()
 */
static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
{
	u8 key[4];
	u32 keycode;
	u8 toggle;
	int i;
	struct dib0700_state *st = d->priv;

	if (st->fw_version >= 0x10200) {
		/* For 1.20 firmware , We need to keep the RC polling
		   callback so we can reuse the input device setup in
		   dvb-usb-remote.c.  However, the actual work is being done
		   in the bulk URB completion handler. */
		return 0;
	}

	i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
	if (i <= 0) {
		err("RC Query Failed");
		return -1;
	}

	/* losing half of KEY_0 events from Philipps rc5 remotes.. */
	if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
		return 0;

	/* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]);  */

	dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */

	d->last_event = 0;
	switch (d->props.rc.core.protocol) {
	case RC_BIT_NEC:
		/* NEC protocol sends repeat code as 0 0 0 FF */
		if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
		    (key[3] == 0xff))
			keycode = d->last_event;
		else {
			keycode = key[3-2] << 8 | key[3-3];
			d->last_event = keycode;
		}

		rc_keydown(d->rc_dev, keycode, 0);
		break;
	default:
		/* RC-5 protocol changes toggle bit on new keypress */
		keycode = key[3-2] << 8 | key[3-3];
		toggle = key[3-1];
		rc_keydown(d->rc_dev, keycode, toggle);

		break;
	}
	return 0;
}

/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
	BAND_UHF | BAND_VHF,

	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
	 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
	| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),

	712,
	41,

	0,
	118,

	0,
	4095,
	0,
	0,

	42598,
	17694,
	45875,
	2621,
	0,
	76,
	139,
	52,
	59,
	107,
	172,
	57,
	70,

	21,
	25,
	28,
	48,

	1,
	{  0,
	   107,
	   51800,
	   24700
	},
};

static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
	BAND_UHF | BAND_VHF,

	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
	 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
	| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),

	712,
	41,

	0,
	118,

	0,
	4095,
	0,
	0,

	42598,
	16384,
	42598,
	    0,

	  0,
	137,
	255,

	  0,
	255,

	0,
	0,

	 0,
	41,

	15,
	25,

	28,
	48,

	0,
};

static struct dibx000_bandwidth_config stk7700p_pll_config = {
	60000, 30000,
	1, 8, 3, 1, 0,
	0, 0, 1, 1, 0,
	(3 << 14) | (1 << 12) | (524 << 0),
	60258167,
	20452225,
	30000000,
};

static struct dib7000m_config stk7700p_dib7000m_config = {
	.dvbt_mode = 1,
	.output_mpeg2_in_188_bytes = 1,
	.quartz_direct = 1,

	.agc_config_count = 1,
	.agc = &stk7700p_7000m_mt2060_agc_config,
	.bw  = &stk7700p_pll_config,

	.gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
};

static struct dib7000p_config stk7700p_dib7000p_config = {
	.output_mpeg2_in_188_bytes = 1,

	.agc_config_count = 1,
	.agc = &stk7700p_7000p_mt2060_agc_config,
	.bw  = &stk7700p_pll_config,

	.gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
};

static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct dib0700_state *st = adap->dev->priv;
	/* unless there is no real power management in DVB - we leave the device on GPIO6 */

	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
	dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(50);

	dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
	dib0700_set_gpio(adap->dev, GPIO9,  GPIO_OUT, 1);

	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
	dib0700_ctrl_clock(adap->dev, 72, 1);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);

	dib0700_set_gpio(adap->dev,  GPIO0, GPIO_OUT, 1);

	st->mt2060_if1[0] = 1220;

	if (dib7000pc_detection(&adap->dev->i2c_adap)) {
		adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
		st->is_dib7000pc = 1;
	} else
		adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);

	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

static struct mt2060_config stk7700p_mt2060_config = {
	0x60
};

static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
	struct dib0700_state *st = adap->dev->priv;
	struct i2c_adapter *tun_i2c;
	s8 a;
	int if1=1220;
	if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
		adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
		if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
	}
	if (st->is_dib7000pc)
		tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
	else
		tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);

	return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700p_mt2060_config,
		if1) == NULL ? -ENODEV : 0;
}

/* DIB7070 generic */
static struct dibx000_agc_config dib7070_agc_config = {
	BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
	 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
	| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),

	600,
	10,

	0,
	118,

	0,
	3530,
	1,
	5,

	65535,
		0,

	65535,
	0,

	0,
	40,
	183,
	206,
	255,
	72,
	152,
	88,
	90,

	17,
	27,
	23,
	51,

	0,
};

static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
{
	deb_info("reset: %d", onoff);
	return dib7000p_set_gpio(fe, 8, 0, !onoff);
}

static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
	deb_info("sleep: %d", onoff);
	return dib7000p_set_gpio(fe, 9, 0, onoff);
}

static struct dib0070_config dib7070p_dib0070_config[2] = {
	{
		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
		.reset = dib7070_tuner_reset,
		.sleep = dib7070_tuner_sleep,
		.clock_khz = 12000,
		.clock_pad_drive = 4,
		.charge_pump = 2,
	}, {
		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
		.reset = dib7070_tuner_reset,
		.sleep = dib7070_tuner_sleep,
		.clock_khz = 12000,
		.charge_pump = 2,
	}
};

static struct dib0070_config dib7770p_dib0070_config = {
	 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
	 .reset = dib7070_tuner_reset,
	 .sleep = dib7070_tuner_sleep,
	 .clock_khz = 12000,
	 .clock_pad_drive = 0,
	 .flip_chip = 1,
	 .charge_pump = 2,
};

static int dib7070_set_param_override(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
	struct dvb_usb_adapter *adap = fe->dvb->priv;
	struct dib0700_adapter_state *state = adap->priv;

	u16 offset;
	u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
	switch (band) {
		case BAND_VHF: offset = 950; break;
		case BAND_UHF:
		default: offset = 550; break;
	}
	deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
	dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
	return state->set_param_save(fe);
}

static int dib7770_set_param_override(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
	struct dvb_usb_adapter *adap = fe->dvb->priv;
	struct dib0700_adapter_state *state = adap->priv;

	 u16 offset;
	 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
	 switch (band) {
	 case BAND_VHF:
		  dib7000p_set_gpio(fe, 0, 0, 1);
		  offset = 850;
		  break;
	 case BAND_UHF:
	 default:
		  dib7000p_set_gpio(fe, 0, 0, 0);
		  offset = 250;
		  break;
	 }
	 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
	 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
	 return state->set_param_save(fe);
}

static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
{
	 struct dib0700_adapter_state *st = adap->priv;
	 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
			 DIBX000_I2C_INTERFACE_TUNER, 1);

	 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
			&dib7770p_dib0070_config) == NULL)
		 return -ENODEV;

	 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
	 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override;
	 return 0;
}

static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct dib0700_adapter_state *st = adap->priv;
	struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);

	if (adap->id == 0) {
		if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
			return -ENODEV;
	} else {
		if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
			return -ENODEV;
	}

	st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
	adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
	return 0;
}

static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index,
		u16 pid, int onoff)
{
	struct dib0700_state *st = adapter->dev->priv;
	if (st->is_dib7000pc)
		return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
	return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
}

static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
{
	struct dib0700_state *st = adapter->dev->priv;
	if (st->is_dib7000pc)
		return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
	return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
}

static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
{
	return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
}

static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
{
	return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
}

static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
	60000, 15000,
	1, 20, 3, 1, 0,
	0, 0, 1, 1, 2,
	(3 << 14) | (1 << 12) | (524 << 0),
	(0 << 25) | 0,
	20452225,
	12000000,
};

static struct dib7000p_config dib7070p_dib7000p_config = {
	.output_mpeg2_in_188_bytes = 1,

	.agc_config_count = 1,
	.agc = &dib7070_agc_config,
	.bw  = &dib7070_bw_config_12_mhz,
	.tuner_is_baseband = 1,
	.spur_protect = 1,

	.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,

	.hostbus_diversity = 1,
};

/* STK7070P */
static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
	if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
	    p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
	else
		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);

	dib0700_ctrl_clock(adap->dev, 72, 1);

	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);

	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
				     &dib7070p_dib7000p_config) != 0) {
		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
		    __func__);
		return -ENODEV;
	}

	adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
		&dib7070p_dib7000p_config);
	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

/* STK7770P */
static struct dib7000p_config dib7770p_dib7000p_config = {
	.output_mpeg2_in_188_bytes = 1,

	.agc_config_count = 1,
	.agc = &dib7070_agc_config,
	.bw  = &dib7070_bw_config_12_mhz,
	.tuner_is_baseband = 1,
	.spur_protect = 1,

	.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,

	.hostbus_diversity = 1,
	.enable_current_mirror = 1,
	.disable_sample_and_hold = 0,
};

static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
	if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
	    p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
	else
		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);

	dib0700_ctrl_clock(adap->dev, 72, 1);

	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);

	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
				     &dib7770p_dib7000p_config) != 0) {
		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
		    __func__);
		return -ENODEV;
	}

	adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
		&dib7770p_dib7000p_config);
	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

/* DIB807x generic */
static struct dibx000_agc_config dib807x_agc_config[2] = {
	{
		BAND_VHF,
		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
		 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
		 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
		 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
		 * P_agc_write=0 */
		(0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
			(0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
			(0 << 0), /* setup*/

		600, /* inv_gain*/
		10,  /* time_stabiliz*/

		0,  /* alpha_level*/
		118,  /* thlock*/

		0,     /* wbd_inv*/
		3530,  /* wbd_ref*/
		1,     /* wbd_sel*/
		5,     /* wbd_alpha*/

		65535,  /* agc1_max*/
		0,  /* agc1_min*/

		65535,  /* agc2_max*/
		0,      /* agc2_min*/

		0,      /* agc1_pt1*/
		40,     /* agc1_pt2*/
		183,    /* agc1_pt3*/
		206,    /* agc1_slope1*/
		255,    /* agc1_slope2*/
		72,     /* agc2_pt1*/
		152,    /* agc2_pt2*/
		88,     /* agc2_slope1*/
		90,     /* agc2_slope2*/

		17,  /* alpha_mant*/
		27,  /* alpha_exp*/
		23,  /* beta_mant*/
		51,  /* beta_exp*/

		0,  /* perform_agc_softsplit*/
	}, {
		BAND_UHF,
		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
		 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
		 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
		 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
		 * P_agc_write=0 */
		(0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
			(0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
			(0 << 0), /* setup */

		600, /* inv_gain*/
		10,  /* time_stabiliz*/

		0,  /* alpha_level*/
		118,  /* thlock*/

		0,     /* wbd_inv*/
		3530,  /* wbd_ref*/
		1,     /* wbd_sel*/
		5,     /* wbd_alpha*/

		65535,  /* agc1_max*/
		0,  /* agc1_min*/

		65535,  /* agc2_max*/
		0,      /* agc2_min*/

		0,      /* agc1_pt1*/
		40,     /* agc1_pt2*/
		183,    /* agc1_pt3*/
		206,    /* agc1_slope1*/
		255,    /* agc1_slope2*/
		72,     /* agc2_pt1*/
		152,    /* agc2_pt2*/
		88,     /* agc2_slope1*/
		90,     /* agc2_slope2*/

		17,  /* alpha_mant*/
		27,  /* alpha_exp*/
		23,  /* beta_mant*/
		51,  /* beta_exp*/

		0,  /* perform_agc_softsplit*/
	}
};

static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
	60000, 15000, /* internal, sampling*/
	1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
	0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
			  ADClkSrc, modulo */
	(3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
	(0 << 25) | 0, /* ifreq = 0.000000 MHz*/
	18179755, /* timf*/
	12000000, /* xtal_hz*/
};

static struct dib8000_config dib807x_dib8000_config[2] = {
	{
		.output_mpeg2_in_188_bytes = 1,

		.agc_config_count = 2,
		.agc = dib807x_agc_config,
		.pll = &dib807x_bw_config_12_mhz,
		.tuner_is_baseband = 1,

		.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
		.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
		.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,

		.hostbus_diversity = 1,
		.div_cfg = 1,
		.agc_control = &dib0070_ctrl_agc_filter,
		.output_mode = OUTMODE_MPEG2_FIFO,
		.drives = 0x2d98,
	}, {
		.output_mpeg2_in_188_bytes = 1,

		.agc_config_count = 2,
		.agc = dib807x_agc_config,
		.pll = &dib807x_bw_config_12_mhz,
		.tuner_is_baseband = 1,

		.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
		.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
		.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,

		.hostbus_diversity = 1,
		.agc_control = &dib0070_ctrl_agc_filter,
		.output_mode = OUTMODE_MPEG2_FIFO,
		.drives = 0x2d98,
	}
};

static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
{
	return dib8000_set_gpio(fe, 5, 0, !onoff);
}

static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
	return dib8000_set_gpio(fe, 0, 0, onoff);
}

static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
    { 240,      7},
    { 0xffff,   6},
};

static struct dib0070_config dib807x_dib0070_config[2] = {
	{
		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
		.reset = dib80xx_tuner_reset,
		.sleep = dib80xx_tuner_sleep,
		.clock_khz = 12000,
		.clock_pad_drive = 4,
		.vga_filter = 1,
		.force_crystal_mode = 1,
		.enable_third_order_filter = 1,
		.charge_pump = 0,
		.wbd_gain = dib8070_wbd_gain_cfg,
		.osc_buffer_state = 0,
		.freq_offset_khz_uhf = -100,
		.freq_offset_khz_vhf = -100,
	}, {
		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
		.reset = dib80xx_tuner_reset,
		.sleep = dib80xx_tuner_sleep,
		.clock_khz = 12000,
		.clock_pad_drive = 2,
		.vga_filter = 1,
		.force_crystal_mode = 1,
		.enable_third_order_filter = 1,
		.charge_pump = 0,
		.wbd_gain = dib8070_wbd_gain_cfg,
		.osc_buffer_state = 0,
		.freq_offset_khz_uhf = -25,
		.freq_offset_khz_vhf = -25,
	}
};

static int dib807x_set_param_override(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
	struct dvb_usb_adapter *adap = fe->dvb->priv;
	struct dib0700_adapter_state *state = adap->priv;

	u16 offset = dib0070_wbd_offset(fe);
	u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
	switch (band) {
	case BAND_VHF:
		offset += 750;
		break;
	case BAND_UHF:  /* fall-thru wanted */
	default:
		offset += 250; break;
	}
	deb_info("WBD for DiB8000: %d\n", offset);
	dib8000_set_wbd_ref(fe, offset);

	return state->set_param_save(fe);
}

static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct dib0700_adapter_state *st = adap->priv;
	struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe,
			DIBX000_I2C_INTERFACE_TUNER, 1);

	if (adap->id == 0) {
		if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
				&dib807x_dib0070_config[0]) == NULL)
			return -ENODEV;
	} else {
		if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
				&dib807x_dib0070_config[1]) == NULL)
			return -ENODEV;
	}

	st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
	adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib807x_set_param_override;
	return 0;
}

static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
	u16 pid, int onoff)
{
	return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
}

static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
		int onoff)
{
	return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
}

/* STK807x */
static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
{
	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);

	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);

	dib0700_ctrl_clock(adap->dev, 72, 1);

	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);

	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
				0x80, 0);

	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
			      &dib807x_dib8000_config[0]);

	return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
}

/* STK807xPVR */
static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
{
	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
	msleep(30);
	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
	msleep(500);
	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);

	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);

	dib0700_ctrl_clock(adap->dev, 72, 1);

	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);

	/* initialize IC 0 */
	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);

	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
			      &dib807x_dib8000_config[0]);

	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
{
	/* initialize IC 1 */
	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);

	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
			      &dib807x_dib8000_config[1]);

	return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

/* STK8096GP */
static struct dibx000_agc_config dib8090_agc_config[2] = {
	{
	BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
	 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
	 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
	| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),

	787,
	10,

	0,
	118,

	0,
	3530,
	1,
	5,

	65535,
	0,

	65535,
	0,

	0,
	32,
	114,
	143,
	144,
	114,
	227,
	116,
	117,

	28,
	26,
	31,
	51,

	0,
	},
	{
	BAND_CBAND,
	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
	 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
	 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
	| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),

	787,
	10,

	0,
	118,

	0,
	3530,
	1,
	5,

	0,
	0,

	65535,
	0,

	0,
	32,
	114,
	143,
	144,
	114,
	227,
	116,
	117,

	28,
	26,
	31,
	51,

	0,
	}
};

static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
	54000, 13500,
	1, 18, 3, 1, 0,
	0, 0, 1, 1, 2,
	(3 << 14) | (1 << 12) | (599 << 0),
	(0 << 25) | 0,
	20199727,
	12000000,
};

static int dib8090_get_adc_power(struct dvb_frontend *fe)
{
	return dib8000_get_adc_power(fe, 1);
}

static void dib8090_agc_control(struct dvb_frontend *fe, u8 restart)
{
	deb_info("AGC control callback: %i\n", restart);
	dib0090_dcc_freq(fe, restart);

	if (restart == 0) /* before AGC startup */
		dib0090_set_dc_servo(fe, 1);
}

static struct dib8000_config dib809x_dib8000_config[2] = {
	{
	.output_mpeg2_in_188_bytes = 1,

	.agc_config_count = 2,
	.agc = dib8090_agc_config,
	.agc_control = dib8090_agc_control,
	.pll = &dib8090_pll_config_12mhz,
	.tuner_is_baseband = 1,

	.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,

	.hostbus_diversity = 1,
	.div_cfg = 0x31,
	.output_mode = OUTMODE_MPEG2_FIFO,
	.drives = 0x2d98,
	.diversity_delay = 48,
	.refclksel = 3,
	}, {
	.output_mpeg2_in_188_bytes = 1,

	.agc_config_count = 2,
	.agc = dib8090_agc_config,
	.agc_control = dib8090_agc_control,
	.pll = &dib8090_pll_config_12mhz,
	.tuner_is_baseband = 1,

	.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,

	.hostbus_diversity = 1,
	.div_cfg = 0x31,
	.output_mode = OUTMODE_DIVERSITY,
	.drives = 0x2d08,
	.diversity_delay = 1,
	.refclksel = 3,
	}
};

static struct dib0090_wbd_slope dib8090_wbd_table[] = {
	/* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
	{ 120,     0, 500,  0,   500, 4 }, /* CBAND */
	{ 170,     0, 450,  0,   450, 4 }, /* CBAND */
	{ 380,    48, 373, 28,   259, 6 }, /* VHF */
	{ 860,    34, 700, 36,   616, 6 }, /* high UHF */
	{ 0xFFFF, 34, 700, 36,   616, 6 }, /* default */
};

static struct dib0090_config dib809x_dib0090_config = {
	.io.pll_bypass = 1,
	.io.pll_range = 1,
	.io.pll_prediv = 1,
	.io.pll_loopdiv = 20,
	.io.adc_clock_ratio = 8,
	.io.pll_int_loop_filt = 0,
	.io.clock_khz = 12000,
	.reset = dib80xx_tuner_reset,
	.sleep = dib80xx_tuner_sleep,
	.clkouttobamse = 1,
	.analog_output = 1,
	.i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
	.use_pwm_agc = 1,
	.clkoutdrive = 1,
	.get_adc_power = dib8090_get_adc_power,
	.freq_offset_khz_uhf = -63,
	.freq_offset_khz_vhf = -143,
	.wbd = dib8090_wbd_table,
	.fref_clock_ratio = 6,
};

static u8 dib8090_compute_pll_parameters(struct dvb_frontend *fe)
{
	u8 optimal_pll_ratio = 20;
	u32 freq_adc, ratio, rest, max = 0;
	u8 pll_ratio;

	for (pll_ratio = 17; pll_ratio <= 20; pll_ratio++) {
		freq_adc = 12 * pll_ratio * (1 << 8) / 16;
		ratio = ((fe->dtv_property_cache.frequency / 1000) * (1 << 8) / 1000) / freq_adc;
		rest = ((fe->dtv_property_cache.frequency / 1000) * (1 << 8) / 1000) - ratio * freq_adc;

		if (rest > freq_adc / 2)
			rest = freq_adc - rest;
		deb_info("PLL ratio=%i rest=%i\n", pll_ratio, rest);
		if ((rest > max) && (rest > 717)) {
			optimal_pll_ratio = pll_ratio;
			max = rest;
		}
	}
	deb_info("optimal PLL ratio=%i\n", optimal_pll_ratio);

	return optimal_pll_ratio;
}

static int dib8096_set_param_override(struct dvb_frontend *fe)
{
	struct dvb_usb_adapter *adap = fe->dvb->priv;
	struct dib0700_adapter_state *state = adap->priv;
	u8 pll_ratio, band = BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
	u16 target, ltgain, rf_gain_limit;
	u32 timf;
	int ret = 0;
	enum frontend_tune_state tune_state = CT_SHUTDOWN;

	switch (band) {
	default:
			deb_info("Warning : Rf frequency  (%iHz) is not in the supported range, using VHF switch ", fe->dtv_property_cache.frequency);
	case BAND_VHF:
			dib8000_set_gpio(fe, 3, 0, 1);
			break;
	case BAND_UHF:
			dib8000_set_gpio(fe, 3, 0, 0);
			break;
	}

	ret = state->set_param_save(fe);
	if (ret < 0)
		return ret;

	if (fe->dtv_property_cache.bandwidth_hz != 6000000) {
		deb_info("only 6MHz bandwidth is supported\n");
		return -EINVAL;
	}

	/** Update PLL if needed ratio **/
	dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0);

	/** Get optimize PLL ratio to remove spurious **/
	pll_ratio = dib8090_compute_pll_parameters(fe);
	if (pll_ratio == 17)
		timf = 21387946;
	else if (pll_ratio == 18)
		timf = 20199727;
	else if (pll_ratio == 19)
		timf = 19136583;
	else
		timf = 18179756;

	/** Update ratio **/
	dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio);

	dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, timf);

	if (band != BAND_CBAND) {
		/* dib0090_get_wbd_target is returning any possible temperature compensated wbd-target */
		target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
		dib8000_set_wbd_ref(fe, target);
	}

	if (band == BAND_CBAND) {
		deb_info("tuning in CBAND - soft-AGC startup\n");
		dib0090_set_tune_state(fe, CT_AGC_START);

		do {
			ret = dib0090_gain_control(fe);
			msleep(ret);
			tune_state = dib0090_get_tune_state(fe);
			if (tune_state == CT_AGC_STEP_0)
				dib8000_set_gpio(fe, 6, 0, 1);
			else if (tune_state == CT_AGC_STEP_1) {
				dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
				if (rf_gain_limit < 2000) /* activate the external attenuator in case of very high input power */
					dib8000_set_gpio(fe, 6, 0, 0);
			}
		} while (tune_state < CT_AGC_STOP);

		deb_info("switching to PWM AGC\n");
		dib0090_pwm_gain_reset(fe);
		dib8000_pwm_agc_reset(fe);
		dib8000_set_tune_state(fe, CT_DEMOD_START);
	} else {
		/* for everything else than CBAND we are using standard AGC */
		deb_info("not tuning in CBAND - standard AGC startup\n");
		dib0090_pwm_gain_reset(fe);
	}

	return 0;
}

static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct dib0700_adapter_state *st = adap->priv;
	struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);

	if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
		return -ENODEV;

	st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
	adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
	return 0;
}

static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
{
	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);

	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);

	dib0700_ctrl_clock(adap->dev, 72, 1);

	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
	msleep(10);
	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);

	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);

	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);

	return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
}

static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
{
	struct dib0700_adapter_state *st = adap->priv;
	struct i2c_adapter *tun_i2c;
	struct dvb_frontend *fe_slave  = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1);

	if (fe_slave) {
		tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
		if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
			return -ENODEV;
		fe_slave->dvb = adap->fe_adap[0].fe->dvb;
		fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
	}
	tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
	if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
		return -ENODEV;

	st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
	adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;

	return 0;
}

static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct dvb_frontend *fe_slave;

	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
	msleep(20);
	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
	msleep(1000);
	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);

	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);

	dib0700_ctrl_clock(adap->dev, 72, 1);

	msleep(20);
	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
	msleep(20);
	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);

	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);

	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
	if (adap->fe_adap[0].fe == NULL)
		return -ENODEV;

	fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
	dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);

	return fe_slave == NULL ?  -ENODEV : 0;
}

/* TFE8096P */
static struct dibx000_agc_config dib8096p_agc_config[2] = {
	{
		.band_caps		= BAND_UHF,
		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
		   P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
		   P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
		   P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
		   P_agc_write=0 */
		.setup			= (0 << 15) | (0 << 14) | (5 << 11)
			| (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
			| (0 << 4) | (5 << 1) | (0 << 0),

		.inv_gain		= 684,
		.time_stabiliz	= 10,

		.alpha_level	= 0,
		.thlock			= 118,

		.wbd_inv		= 0,
		.wbd_ref		= 1200,
		.wbd_sel		= 3,
		.wbd_alpha		= 5,

		.agc1_max		= 65535,
		.agc1_min		= 0,

		.agc2_max		= 32767,
		.agc2_min		= 0,

		.agc1_pt1		= 0,
		.agc1_pt2		= 0,
		.agc1_pt3		= 105,
		.agc1_slope1	= 0,
		.agc1_slope2	= 156,
		.agc2_pt1		= 105,
		.agc2_pt2		= 255,
		.agc2_slope1	= 54,
		.agc2_slope2	= 0,

		.alpha_mant		= 28,
		.alpha_exp		= 26,
		.beta_mant		= 31,
		.beta_exp		= 51,

		.perform_agc_softsplit = 0,
	} , {
		.band_caps		= BAND_FM | BAND_VHF | BAND_CBAND,
		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
		   P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
		   P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
		   P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
		   P_agc_write=0 */
		.setup			= (0 << 15) | (0 << 14) | (5 << 11)
			| (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
			| (0 << 4) | (5 << 1) | (0 << 0),

		.inv_gain		= 732,
		.time_stabiliz  = 10,

		.alpha_level	= 0,
		.thlock			= 118,

		.wbd_inv		= 0,
		.wbd_ref		= 1200,
		.wbd_sel		= 3,
		.wbd_alpha		= 5,

		.agc1_max		= 65535,
		.agc1_min		= 0,

		.agc2_max		= 32767,
		.agc2_min		= 0,

		.agc1_pt1		= 0,
		.agc1_pt2		= 0,
		.agc1_pt3		= 98,
		.agc1_slope1	= 0,
		.agc1_slope2	= 167,
		.agc2_pt1		= 98,
		.agc2_pt2		= 255,
		.agc2_slope1	= 52,
		.agc2_slope2	= 0,

		.alpha_mant		= 28,
		.alpha_exp		= 26,
		.beta_mant		= 31,
		.beta_exp		= 51,

		.perform_agc_softsplit = 0,
	}
};

static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = {
	108000, 13500,
	1, 9, 1, 0, 0,
	0, 0, 0, 0, 2,
	(3 << 14) | (1 << 12) | (524 << 0),
	(0 << 25) | 0,
	20199729,
	12000000,
};

static struct dib8000_config tfe8096p_dib8000_config = {
	.output_mpeg2_in_188_bytes	= 1,
	.hostbus_diversity			= 1,
	.update_lna					= NULL,

	.agc_config_count			= 2,
	.agc						= dib8096p_agc_config,
	.pll						= &dib8096p_clock_config_12_mhz,

	.gpio_dir					= DIB8000_GPIO_DEFAULT_DIRECTIONS,
	.gpio_val					= DIB8000_GPIO_DEFAULT_VALUES,
	.gpio_pwm_pos				= DIB8000_GPIO_DEFAULT_PWM_POS,

	.agc_control				= NULL,
	.diversity_delay			= 48,
	.output_mode				= OUTMODE_MPEG2_FIFO,
	.enMpegOutput				= 1,
};

static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
	{ 380, 81, 850, 64, 540, 4},
	{ 860, 51, 866, 21, 375, 4},
	{1700, 0, 250, 0, 100, 6},
	{2600, 0, 250, 0, 100, 6},
	{ 0xFFFF, 0, 0, 0, 0, 0},
};

static const struct dib0090_config tfe8096p_dib0090_config = {
	.io.clock_khz			= 12000,
	.io.pll_bypass			= 0,
	.io.pll_range			= 0,
	.io.pll_prediv			= 3,
	.io.pll_loopdiv			= 6,
	.io.adc_clock_ratio		= 0,
	.io.pll_int_loop_filt	= 0,
	.reset					= dib8096p_tuner_sleep,
	.sleep					= dib8096p_tuner_sleep,

	.freq_offset_khz_uhf	= -143,
	.freq_offset_khz_vhf	= -143,

	.get_adc_power			= dib8090_get_adc_power,

	.clkouttobamse			= 1,
	.analog_output			= 0,

	.wbd_vhf_offset			= 0,
	.wbd_cband_offset		= 0,
	.use_pwm_agc			= 1,
	.clkoutdrive			= 0,

	.fref_clock_ratio		= 1,

	.wbd					= dib8096p_wbd_table,

	.ls_cfg_pad_drv			= 0,
	.data_tx_drv			= 0,
	.low_if					= NULL,
	.in_soc					= 1,
	.force_cband_input		= 0,
};

struct dibx090p_adc {
	u32 freq;			/* RF freq MHz */
	u32 timf;			/* New Timf */
	u32 pll_loopdiv;	/* New prediv */
	u32 pll_prediv;		/* New loopdiv */
};

struct dibx090p_best_adc {
	u32 timf;
	u32 pll_loopdiv;
	u32 pll_prediv;
};

static int dib8096p_get_best_sampling(struct dvb_frontend *fe, struct dibx090p_best_adc *adc)
{
	u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
	u16 xtal = 12000;
	u16 fcp_min = 1900;  /* PLL, Minimum Frequency of phase comparator (KHz) */
	u16 fcp_max = 20000; /* PLL, Maximum Frequency of phase comparator (KHz) */
	u32 fmem_max = 140000; /* 140MHz max SDRAM freq */
	u32 fdem_min = 66000;
	u32 fcp = 0, fs = 0, fdem = 0, fmem = 0;
	u32 harmonic_id = 0;

	adc->timf = 0;
	adc->pll_loopdiv = loopdiv;
	adc->pll_prediv = prediv;

	deb_info("bandwidth = %d", fe->dtv_property_cache.bandwidth_hz);

	/* Find Min and Max prediv */
	while ((xtal / max_prediv) >= fcp_min)
		max_prediv++;

	max_prediv--;
	min_prediv = max_prediv;
	while ((xtal / min_prediv) <= fcp_max) {
		min_prediv--;
		if (min_prediv == 1)
			break;
	}
	deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);

	min_prediv = 1;

	for (prediv = min_prediv; prediv < max_prediv; prediv++) {
		fcp = xtal / prediv;
		if (fcp > fcp_min && fcp < fcp_max) {
			for (loopdiv = 1; loopdiv < 64; loopdiv++) {
				fmem = ((xtal/prediv) * loopdiv);
				fdem = fmem / 2;
				fs   = fdem / 4;

				/* test min/max system restrictions */
				if ((fdem >= fdem_min) && (fmem <= fmem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz / 1000)) {
					spur = 0;
					/* test fs harmonics positions */
					for (harmonic_id = (fe->dtv_property_cache.frequency / (1000 * fs));  harmonic_id <= ((fe->dtv_property_cache.frequency / (1000 * fs)) + 1); harmonic_id++) {
						if (((fs * harmonic_id) >= (fe->dtv_property_cache.frequency / 1000 - (fe->dtv_property_cache.bandwidth_hz / 2000))) &&  ((fs * harmonic_id) <= (fe->dtv_property_cache.frequency / 1000 + (fe->dtv_property_cache.bandwidth_hz / 2000)))) {
							spur = 1;
							break;
						}
					}

					if (!spur) {
						adc->pll_loopdiv = loopdiv;
						adc->pll_prediv = prediv;
						adc->timf = (4260880253U / fdem) * (1 << 8);
						adc->timf += ((4260880253U % fdem) << 8) / fdem;

						deb_info("RF %6d; BW %6d; Xtal %6d; Fmem %6d; Fdem %6d; Fs %6d; Prediv %2d; Loopdiv %2d; Timf %8d;", fe->dtv_property_cache.frequency, fe->dtv_property_cache.bandwidth_hz, xtal, fmem, fdem, fs, prediv, loopdiv, adc->timf);
						break;
					}
				}
			}
		}
		if (!spur)
			break;
	}

	if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
		return -EINVAL;
	return 0;
}

static int dib8096p_agc_startup(struct dvb_frontend *fe)
{
	struct dvb_usb_adapter *adap = fe->dvb->priv;
	struct dib0700_adapter_state *state = adap->priv;
	struct dibx000_bandwidth_config pll;
	struct dibx090p_best_adc adc;
	u16 target;
	int ret;

	ret = state->set_param_save(fe);
	if (ret < 0)
		return ret;
	memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));

	dib0090_pwm_gain_reset(fe);
	/* dib0090_get_wbd_target is returning any possible
	   temperature compensated wbd-target */