Changeset 698
- Timestamp:
- 01/15/00 20:01:54 (13 years ago)
- Files:
-
- 1 modified
-
lm-sensors/trunk/kernel/busses/i2c-voodoo3.c (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lm-sensors/trunk/kernel/busses/i2c-voodoo3.c
r684 r698 3 3 monitoring 4 4 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> 7 8 8 9 Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and … … 59 60 #ifndef PCI_DEVICE_ID_3DFX_VOODOO3 60 61 #define PCI_DEVICE_ID_3DFX_VOODOO3 0x05 62 #endif 63 #ifndef PCI_DEVICE_ID_3DFX_BANSHEE 64 #define PCI_DEVICE_ID_3DFX_BANSHEE 0x03 61 65 #endif 62 66 … … 84 88 static int Voodoo3_I2CWrite_byte_data(int addr,int command,int data); 85 89 static int Voodoo3_I2CWrite_word(int addr,int command,long data); 86 static void config_v3(struct pci_dev *dev, int num); 90 static 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); 93 static void Voodoo3_DDCStart(void); 94 static void Voodoo3_DDCStop(void); 95 static int Voodoo3_DDCAck(int ackit); 96 static int Voodoo3_DDCReadByte(int ackit); 97 static int Voodoo3_DDCSendByte(unsigned char data); 98 static int Voodoo3_DDCBusCheck(void); 99 static int Voodoo3_DDCRead_byte(int addr); 100 static int Voodoo3_DDCRead_byte_data(int addr,int command); 101 static int Voodoo3_DDCRead_word(int addr,int command); 102 static int Voodoo3_DDCWrite_byte(int addr,int command); 103 static int Voodoo3_DDCWrite_byte_data(int addr,int command,int data); 104 static int Voodoo3_DDCWrite_word(int addr,int command,long data); 105 static void config_v3(struct pci_dev *dev); 87 106 static void voodoo3_inc(struct i2c_adapter *adapter); 88 107 static void voodoo3_dec(struct i2c_adapter *adapter); … … 105 124 }; 106 125 107 static struct i2c_adapter voodoo3_ adapter = {126 static struct i2c_adapter voodoo3_i2c_adapter = { 108 127 "unset", 109 128 I2C_ALGO_SMBUS | I2C_HW_SMBUS_VOODOO3, … … 116 135 }; 117 136 137 static 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 148 static 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 118 159 static int __initdata voodoo3_initialized; 119 160 static unsigned short voodoo3_smba = 0; 120 static unsigned int state=0xcf 980020;161 static unsigned int state=0xcffc0020; 121 162 static unsigned char *mem; 122 163 static int v3_num; … … 127 168 } 128 169 129 130 170 extern inline unsigned int readlong(int off) 131 171 { … … 138 178 udelay(10); 139 179 } 180 181 /* For I2C BUS */ 140 182 141 183 extern inline void dat(int data) … … 162 204 return((readlong(0x78)&(1<<27) )!=0 ); 163 205 } 206 207 /* For DDC BUS */ 208 209 extern inline void ddc_dat(int data) 210 { 211 state&=~(1<<20); 212 if (data) 213 state|=(1<<20); 214 } 215 216 extern inline void ddc_clkon(void) 217 { 218 state|=(1<<19); 219 } 220 221 extern inline void ddc_clkoff(void) 222 { 223 state&=~(1<<19); 224 } 225 226 extern 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 */ 164 234 165 235 /* Changing the Data line while clock is 'on' (high) is a … … 196 266 int Voodoo3_I2CAck(int ackit) 197 267 { 198 int ack ;268 int ack=0; 199 269 200 270 out(); … … 260 330 return 0; 261 331 } 332 333 /* For DDC BUS */ 334 335 void 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 348 void 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 363 int Voodoo3_DDCAck(int ackit) 364 { 365 int 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 378 int 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 395 int 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 413 int 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 */ 262 424 263 425 int Voodoo3_I2CRead_byte(int addr) … … 413 575 } 414 576 415 void config_v3(struct pci_dev *dev, int num) 577 /* For DDC Bus */ 578 579 int 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); 588 ENDREAD1: Voodoo3_DDCStop(); 589 return this_dat; 590 } 591 592 int 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); 604 ENDREAD2: Voodoo3_DDCStop(); 605 return this_dat; 606 } 607 608 int 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); 618 ENDREAD3: Voodoo3_DDCStop(); 619 return this_dat; 620 } 621 622 int Voodoo3_DDCWrite_byte(int addr,int command) 623 { 624 int 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; } 632 ENDWRITE1: Voodoo3_DDCStop(); 633 return result; 634 } 635 636 int Voodoo3_DDCWrite_byte_data(int addr,int command,int data) 637 { 638 int 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; } 649 ENDWRITE2: Voodoo3_DDCStop(); 650 return result; 651 } 652 653 654 int Voodoo3_DDCWrite_word(int addr,int command,long data) 655 { 656 int 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; } 670 ENDWRITE3: Voodoo3_DDCStop(); 671 return result; 672 } 673 674 /* Configures the chip */ 675 676 void config_v3(struct pci_dev *dev) 416 677 { 417 678 unsigned int cadr; … … 430 691 431 692 *((unsigned int *)(mem+0x70))=0x8160; 432 *((unsigned int *)(mem+0x78))=0xcf 980020;693 *((unsigned int *)(mem+0x78))=0xcffc0020; 433 694 printk("i2c-voodoo3: Using Banshee/Voodoo3 at 0x%p\n",mem); 434 695 } … … 448 709 dev = NULL; 449 710 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); 455 715 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 } 456 727 } while(dev); 457 728 … … 460 731 return 0; 461 732 } else { 462 printk(KERN_INFO " v3tv: No Voodoo3 found.\n");733 printk(KERN_INFO "i2c-voodoo3: No Voodoo3 found.\n"); 463 734 return -ENODEV; 464 735 } 465 736 } 466 737 738 /* For I2C BUS */ 467 739 468 740 /* Return -1 on error. See smbus.h for more information */ … … 471 743 u8 command, int size, union i2c_smbus_data * data) 472 744 { 473 int temp=0;745 int temp=0; 474 746 475 747 if (Voodoo3_BusCheck()) return -1; … … 517 789 } 518 790 791 /* For DDC BUS */ 792 793 /* Return -1 on error. See smbus.h for more information */ 794 s32 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 832 TESTACK: if (temp < 0) { 833 return -1; 834 } 835 return 0; 836 } 837 519 838 void voodoo3_inc(struct i2c_adapter *adapter) 520 839 { … … 552 871 } 553 872 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))) { 556 875 printk("i2c-voodoo3.o: Adapter registration failed, module not inserted.\n"); 557 876 voodoo3_cleanup(); 558 877 return res; 559 878 } 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 } 560 886 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"); 562 888 return 0; 563 889 } … … 568 894 569 895 iounmap(mem); 570 if (voodoo3_initialized >= 2)896 if (voodoo3_initialized >= 3) 571 897 { 572 if ((res = i2c_del_adapter(&voodoo3_ adapter))) {898 if ((res = i2c_del_adapter(&voodoo3_ddc_adapter))) { 573 899 printk("i2c-voodoo3.o: i2c_del_adapter failed, module not removed\n"); 574 900 return res; … … 576 902 voodoo3_initialized--; 577 903 } 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 } 578 912 if (voodoo3_initialized >= 1) { 579 913 voodoo3_initialized--; … … 586 920 #ifdef MODULE 587 921 588 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com> and Ralph Metzler <rjkm@thp.uni-koeln.de>");922 MODULE_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>"); 589 923 MODULE_DESCRIPTION("Voodoo3 I2C/SMBus driver"); 590 924
