Changeset 698

Show
Ignore:
Timestamp:
01/15/00 20:01:54 (9 years ago)
Author:
mds
Message:

(mds) Add Banshee support and DDC bus support.

Simultaneous DDC and I2C access may cause errors.
No support for multiple Voodoo3/Banshee chips, only first one
is handled.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lm-sensors/trunk/kernel/busses/i2c-voodoo3.c

    r684 r698  
    33              monitoring 
    44    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>, 
    5     Philip Edelbrock <phil@netroedge.com> and  
    6     Ralph Metzler <rjkm@thp.uni-koeln.de> 
     5    Philip Edelbrock <phil@netroedge.com>, 
     6    Ralph Metzler <rjkm@thp.uni-koeln.de>, and 
     7    Mark D. Studebaker <mdsxyz123@yahoo.com> 
    78     
    89    Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and 
     
    5960#ifndef PCI_DEVICE_ID_3DFX_VOODOO3 
    6061#define PCI_DEVICE_ID_3DFX_VOODOO3 0x05 
     62#endif 
     63#ifndef PCI_DEVICE_ID_3DFX_BANSHEE 
     64#define PCI_DEVICE_ID_3DFX_BANSHEE 0x03 
    6165#endif 
    6266 
     
    8488static int Voodoo3_I2CWrite_byte_data(int addr,int command,int data); 
    8589static int Voodoo3_I2CWrite_word(int addr,int command,long data); 
    86 static void config_v3(struct pci_dev *dev, int num); 
     90static s32 voodoo3_ddc_access(struct i2c_adapter *adap, u16 addr,  
     91                          unsigned short flags, char read_write, 
     92                          u8 command, int size, union i2c_smbus_data * data); 
     93static void Voodoo3_DDCStart(void); 
     94static void Voodoo3_DDCStop(void); 
     95static int Voodoo3_DDCAck(int ackit); 
     96static int Voodoo3_DDCReadByte(int ackit); 
     97static int Voodoo3_DDCSendByte(unsigned char data); 
     98static int Voodoo3_DDCBusCheck(void); 
     99static int Voodoo3_DDCRead_byte(int addr); 
     100static int Voodoo3_DDCRead_byte_data(int addr,int command); 
     101static int Voodoo3_DDCRead_word(int addr,int command); 
     102static int Voodoo3_DDCWrite_byte(int addr,int command); 
     103static int Voodoo3_DDCWrite_byte_data(int addr,int command,int data); 
     104static int Voodoo3_DDCWrite_word(int addr,int command,long data); 
     105static void config_v3(struct pci_dev *dev); 
    87106static void voodoo3_inc(struct i2c_adapter *adapter); 
    88107static void voodoo3_dec(struct i2c_adapter *adapter); 
     
    105124}; 
    106125 
    107 static struct i2c_adapter voodoo3_adapter = { 
     126static struct i2c_adapter voodoo3_i2c_adapter = { 
    108127 "unset", 
    109128 I2C_ALGO_SMBUS | I2C_HW_SMBUS_VOODOO3, 
     
    116135}; 
    117136 
     137static struct i2c_algorithm ddc_algorithm = { 
     138  /* name */            "DDC I2C adapter", 
     139  /* id */              I2C_ALGO_SMBUS, 
     140  /* master_xfer */     NULL, 
     141  /* smbus_access */    &voodoo3_ddc_access, 
     142  /* slave_send */      NULL, 
     143  /* slave_rcv */       NULL, 
     144  /* algo_control */    NULL, 
     145  /* functionality */   voodoo3_func, 
     146}; 
     147 
     148static struct i2c_adapter voodoo3_ddc_adapter = { 
     149 "unset", 
     150 I2C_ALGO_SMBUS | I2C_HW_SMBUS_VOODOO3, 
     151 &ddc_algorithm, 
     152 NULL, 
     153 voodoo3_inc, 
     154 voodoo3_dec, 
     155 NULL, 
     156 NULL, 
     157}; 
     158 
    118159static int __initdata voodoo3_initialized; 
    119160static unsigned short voodoo3_smba = 0; 
    120 static unsigned int state=0xcf980020; 
     161static unsigned int state=0xcffc0020; 
    121162static unsigned char *mem; 
    122163static int v3_num; 
     
    127168} 
    128169 
    129  
    130170extern inline unsigned int readlong(int off) 
    131171{ 
     
    138178        udelay(10); 
    139179} 
     180 
     181/* For I2C BUS */ 
    140182 
    141183extern inline void dat(int data) 
     
    162204        return((readlong(0x78)&(1<<27) )!=0 ); 
    163205} 
     206 
     207/* For DDC BUS */ 
     208 
     209extern inline void ddc_dat(int data) 
     210{ 
     211  state&=~(1<<20); 
     212  if (data) 
     213    state|=(1<<20); 
     214} 
     215 
     216extern inline void ddc_clkon(void) 
     217{ 
     218  state|=(1<<19); 
     219} 
     220 
     221extern inline void ddc_clkoff(void) 
     222{ 
     223  state&=~(1<<19); 
     224} 
     225 
     226extern inline int ddc_rdat(void) 
     227{ 
     228        ddc_dat(1); 
     229        out(); 
     230        return((readlong(0x78)&(1<<22) )!=0 ); 
     231} 
     232 
     233/* For I2C BUS */ 
    164234 
    165235/* Changing the Data line while clock is 'on' (high) is a 
     
    196266int Voodoo3_I2CAck(int ackit) 
    197267{ 
    198 int ack
     268int ack=0
    199269 
    200270  out(); 
     
    260330  return 0; 
    261331} 
     332 
     333/* For DDC BUS */ 
     334 
     335void Voodoo3_DDCStart(void) 
     336{ 
     337  ddc_clkon(); /* in theory, clk is already on */ 
     338  out(); 
     339  out(); 
     340  out(); 
     341  out(); 
     342  ddc_dat(0); 
     343  out(); 
     344  ddc_clkoff(); 
     345  out(); 
     346} 
     347 
     348void Voodoo3_DDCStop(void) 
     349{ 
     350  ddc_dat(0); 
     351  out(); 
     352  ddc_clkon(); 
     353  out(); 
     354  ddc_dat(1); 
     355  out(); 
     356  ddc_clkoff(); 
     357  out(); 
     358  out(); 
     359  ddc_clkon(); 
     360  out(); 
     361} 
     362 
     363int Voodoo3_DDCAck(int ackit) 
     364{ 
     365int ack=0; 
     366 
     367  out(); 
     368  ddc_clkon(); 
     369  if (!ackit) { 
     370   ack=ddc_rdat(); 
     371  } else { ddc_dat(0); } 
     372  out(); 
     373  ddc_clkoff(); 
     374  out(); 
     375  return ack; 
     376} 
     377 
     378int Voodoo3_DDCReadByte(int ackit) 
     379{ 
     380  int i,temp; 
     381  unsigned char data=0; 
     382 
     383  for (i=7; i>=0; i--) { 
     384    out(); 
     385    ddc_clkon(); 
     386    data|=(ddc_rdat()<<i); 
     387    out(); 
     388    ddc_clkoff(); 
     389    out(); 
     390  } 
     391  temp=Voodoo3_DDCAck(ackit); 
     392  return data; 
     393} 
     394 
     395int Voodoo3_DDCSendByte(unsigned char data) 
     396{ 
     397  int i,temp; 
     398 
     399  for (i=7; i>=0; i--) { 
     400    ddc_dat(temp=data&(1<<i)); 
     401    out(); 
     402    ddc_clkon(); 
     403    out(); 
     404    out(); 
     405    ddc_clkoff(); 
     406    out(); 
     407  } 
     408  temp=Voodoo3_DDCAck(0); 
     409  return temp; 
     410} 
     411 
     412 
     413int Voodoo3_DDCBusCheck(void) { 
     414/* Check the bus to see if it is in use */ 
     415 
     416  if (! ddc_rdat()) { 
     417    printk("i2c-voodoo3: I2C bus in use or hung!  Try again later.\n"); 
     418    return 1; 
     419  } 
     420  return 0; 
     421} 
     422 
     423/* For I2C Bus */ 
    262424 
    263425int Voodoo3_I2CRead_byte(int addr) 
     
    413575} 
    414576 
    415 void config_v3(struct pci_dev *dev, int num) 
     577/* For DDC Bus */ 
     578 
     579int Voodoo3_DDCRead_byte(int addr) 
     580
     581        int this_dat=0; 
     582 
     583        Voodoo3_DDCStart(); 
     584        if (Voodoo3_DDCSendByte(addr)) {  
     585          this_dat=-1; 
     586          goto ENDREAD1; } 
     587        this_dat=Voodoo3_DDCReadByte(0); 
     588ENDREAD1: Voodoo3_DDCStop(); 
     589        return this_dat; 
     590
     591 
     592int Voodoo3_DDCRead_byte_data(int addr,int command) 
     593
     594        int this_dat=0; 
     595 
     596        Voodoo3_DDCStart(); 
     597        if (Voodoo3_DDCSendByte(addr)) {  
     598          this_dat=-1; 
     599          goto ENDREAD2; } 
     600        if (!Voodoo3_DDCSendByte(command)) {  
     601          this_dat=-1; 
     602          goto ENDREAD2; } 
     603        this_dat=Voodoo3_DDCReadByte(0); 
     604ENDREAD2: Voodoo3_DDCStop(); 
     605        return this_dat; 
     606
     607 
     608int Voodoo3_DDCRead_word(int addr,int command) 
     609
     610        int this_dat=0; 
     611 
     612        Voodoo3_DDCStart(); 
     613        if (Voodoo3_DDCSendByte(addr)) {  
     614          this_dat=-1; 
     615          goto ENDREAD3; } 
     616        this_dat=Voodoo3_DDCReadByte(1); 
     617        this_dat|=(Voodoo3_DDCReadByte(0)<<8); 
     618ENDREAD3: Voodoo3_DDCStop(); 
     619        return this_dat; 
     620
     621 
     622int Voodoo3_DDCWrite_byte(int addr,int command) 
     623
     624int result=0; 
     625 
     626        Voodoo3_DDCStart(); 
     627        if (Voodoo3_DDCSendByte(addr)) {  
     628          result=-1; 
     629          goto ENDWRITE1; } 
     630        if (Voodoo3_DDCSendByte(command)) { 
     631          result=-1; } 
     632ENDWRITE1: Voodoo3_DDCStop(); 
     633        return result; 
     634
     635 
     636int Voodoo3_DDCWrite_byte_data(int addr,int command,int data) 
     637
     638int result=0; 
     639 
     640        Voodoo3_DDCStart(); 
     641        if (Voodoo3_DDCSendByte(addr)) {  
     642          result=-1; 
     643          goto ENDWRITE2; } 
     644        if (Voodoo3_DDCSendByte(command)) { 
     645          result=-1; 
     646          goto ENDWRITE2; } 
     647        if (Voodoo3_DDCSendByte(data)) { 
     648        result=-1; } 
     649ENDWRITE2: Voodoo3_DDCStop(); 
     650        return result; 
     651
     652 
     653 
     654int Voodoo3_DDCWrite_word(int addr,int command,long data) 
     655
     656int result=0; 
     657 
     658        Voodoo3_DDCStart(); 
     659        if (Voodoo3_DDCSendByte(addr)) {  
     660          result=-1; 
     661          goto ENDWRITE3; } 
     662        if (Voodoo3_DDCSendByte(command)) { 
     663          result=-1; 
     664          goto ENDWRITE3; } 
     665        if (Voodoo3_DDCSendByte(data & 0x0FF)) { 
     666        result=-1;  
     667        goto ENDWRITE3; } 
     668        if (Voodoo3_DDCSendByte((data &0x0FF00)>>8)) { 
     669        result=-1; } 
     670ENDWRITE3: Voodoo3_DDCStop(); 
     671        return result; 
     672
     673 
     674/* Configures the chip */ 
     675 
     676void config_v3(struct pci_dev *dev) 
    416677{ 
    417678        unsigned int cadr; 
     
    430691         
    431692        *((unsigned int *)(mem+0x70))=0x8160; 
    432         *((unsigned int *)(mem+0x78))=0xcf980020; 
     693        *((unsigned int *)(mem+0x78))=0xcffc0020; 
    433694        printk("i2c-voodoo3: Using Banshee/Voodoo3 at 0x%p\n",mem); 
    434695} 
     
    448709        dev = NULL; 
    449710        do { 
    450                 dev = pci_find_device(PCI_VENDOR_ID_3DFX, 
    451                                            PCI_DEVICE_ID_3DFX_VOODOO3,dev); 
    452                 if(dev && !v3_num) { 
    453                         config_v3(dev,v3_num++); 
    454                 } else 
     711                if((dev = pci_find_device(PCI_VENDOR_ID_3DFX, 
     712                                           PCI_DEVICE_ID_3DFX_VOODOO3,dev))) { 
     713                        if(!v3_num) 
     714                                config_v3(dev); 
    455715                        v3_num++; 
     716                } 
     717        } while(dev); 
     718 
     719        dev = NULL; 
     720        do { 
     721                if((dev = pci_find_device(PCI_VENDOR_ID_3DFX, 
     722                                           PCI_DEVICE_ID_3DFX_BANSHEE,dev))) { 
     723                        if(!v3_num) 
     724                                config_v3(dev); 
     725                        v3_num++; 
     726                } 
    456727        } while(dev); 
    457728 
     
    460731                return 0; 
    461732        } else { 
    462                 printk(KERN_INFO "v3tv: No Voodoo3 found.\n"); 
     733                printk(KERN_INFO "i2c-voodoo3: No Voodoo3 found.\n"); 
    463734                return -ENODEV; 
    464735        } 
    465736} 
    466737 
     738/* For I2C BUS */ 
    467739 
    468740/* Return -1 on error. See smbus.h for more information */ 
     
    471743                   u8 command, int size, union i2c_smbus_data * data) 
    472744{ 
    473 int temp=0; 
     745  int temp=0; 
    474746 
    475747  if (Voodoo3_BusCheck()) return -1; 
     
    517789} 
    518790 
     791/* For DDC BUS */ 
     792 
     793/* Return -1 on error. See smbus.h for more information */ 
     794s32 voodoo3_ddc_access(struct i2c_adapter *adap, u16 addr,  
     795                   unsigned short flags, char read_write, 
     796                   u8 command, int size, union i2c_smbus_data * data) 
     797{ 
     798  int temp=0; 
     799 
     800  if (Voodoo3_DDCBusCheck()) return -1; 
     801 
     802  if ((read_write != I2C_SMBUS_READ) && (read_write != I2C_SMBUS_WRITE)) { 
     803        printk("i2c-voodoo3: Unknown read_write command! (0x%X)\n",read_write); 
     804        return -1; 
     805  } 
     806  addr=((addr & 0x7f) << 1) | (read_write & 0x01); 
     807  switch(size) { 
     808    case I2C_SMBUS_QUICK: 
     809        Voodoo3_DDCStart(); 
     810        if (Voodoo3_DDCSendByte(addr)) {  
     811          return -1; } 
     812    case I2C_SMBUS_BYTE: 
     813        if (read_write == I2C_SMBUS_READ) { temp=Voodoo3_DDCRead_byte(addr); data->byte=temp; 
     814        } else { temp=Voodoo3_DDCWrite_byte(addr,command); } 
     815        goto TESTACK; 
     816    case I2C_SMBUS_BYTE_DATA: 
     817        if (read_write == I2C_SMBUS_READ) { temp=Voodoo3_DDCRead_byte_data(addr,command); data->byte=temp; 
     818        } else { temp=Voodoo3_DDCWrite_byte_data(addr,command,data->byte); } 
     819        goto TESTACK; 
     820    case I2C_SMBUS_WORD_DATA: 
     821        if (read_write == I2C_SMBUS_READ) { temp=Voodoo3_DDCRead_word(addr,command); data->word=temp; 
     822        } else { temp=Voodoo3_DDCWrite_word(addr,command,data->word); } 
     823        goto TESTACK; 
     824    case I2C_SMBUS_PROC_CALL: 
     825        printk("i2c-voodoo3: Proc call not supported.\n"); 
     826        return -1; 
     827    case I2C_SMBUS_BLOCK_DATA: 
     828        printk("i2c-voodoo3: Block transfers not supported yet.\n"); 
     829        return -1; 
     830  } 
     831 
     832TESTACK: if (temp < 0) { 
     833                return -1; 
     834          } 
     835        return 0; 
     836} 
     837 
    519838void voodoo3_inc(struct i2c_adapter *adapter) 
    520839{ 
     
    552871  } 
    553872  voodoo3_initialized ++; 
    554   sprintf(voodoo3_adapter.name,"SMBus Voodoo3 adapter at %04x",voodoo3_smba); 
    555   if ((res = i2c_add_adapter(&voodoo3_adapter))) { 
     873  sprintf(voodoo3_i2c_adapter.name,"SMBus Voodoo3 adapter at %04x",voodoo3_smba); 
     874  if ((res = i2c_add_adapter(&voodoo3_i2c_adapter))) { 
    556875    printk("i2c-voodoo3.o: Adapter registration failed, module not inserted.\n"); 
    557876    voodoo3_cleanup(); 
    558877    return res; 
    559878  } 
     879  voodoo3_initialized ++; 
     880  sprintf(voodoo3_ddc_adapter.name,"DDC Voodoo3 adapter at %04x",voodoo3_smba); 
     881  if ((res = i2c_add_adapter(&voodoo3_ddc_adapter))) { 
     882    printk("i2c-voodoo3.o: Adapter registration failed, module not inserted.\n"); 
     883    voodoo3_cleanup(); 
     884    return res; 
     885  } 
    560886  voodoo3_initialized++; 
    561   printk("i2c-voodoo3.o: Voodoo3 I2C bus detected and initialized\n"); 
     887  printk("i2c-voodoo3.o: Voodoo3 I2C and DDC busses detected and initialized\n"); 
    562888  return 0; 
    563889} 
     
    568894   
    569895  iounmap(mem); 
    570   if (voodoo3_initialized >= 2
     896  if (voodoo3_initialized >= 3
    571897  { 
    572     if ((res = i2c_del_adapter(&voodoo3_adapter))) { 
     898    if ((res = i2c_del_adapter(&voodoo3_ddc_adapter))) { 
    573899      printk("i2c-voodoo3.o: i2c_del_adapter failed, module not removed\n"); 
    574900      return res; 
     
    576902      voodoo3_initialized--; 
    577903  } 
     904  if (voodoo3_initialized >= 2) 
     905  { 
     906    if ((res = i2c_del_adapter(&voodoo3_i2c_adapter))) { 
     907      printk("i2c-voodoo3.o: i2c_del_adapter failed, module not removed\n"); 
     908      return res; 
     909    } else 
     910      voodoo3_initialized--; 
     911  } 
    578912  if (voodoo3_initialized >= 1) { 
    579913    voodoo3_initialized--; 
     
    586920#ifdef MODULE 
    587921 
    588 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com> and Ralph Metzler <rjkm@thp.uni-koeln.de>"); 
     922MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com>, Ralph Metzler <rjkm@thp.uni-koeln.de>, and Mark D. Studebaker <mdsxyz123@yahoo.com>"); 
    589923MODULE_DESCRIPTION("Voodoo3 I2C/SMBus driver"); 
    590924