Einzelnen Beitrag anzeigen

Razor
(Gast)

n/a Beiträge
 
#161

Re: [Tool] GPU - Temperaturanzeige (für nVidia Grafikkarten.

  Alt 13. Nov 2007, 11:04
I got information that ATI uses special I2C
Delphi-Quellcode:
    i2c-radeon.c - Part of lm_sensors, Linux kernel modules for hardware
              monitoring
    Copyright (C) 1998-2004 The LM Sensors Team
    
    Based on i2c-savage4.c.

    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; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/param.h> /* for HZ */
#include "version.h"

/* Radeon defines */
#define RADEON_GPIO_VGA_DDC   0x0060
#define RADEON_GPIO_DVI_DDC   0x0064

/* bit locations in the registers */
#define I2C_SDA_IN      (1 << 8)
#define I2C_SCL_IN      (1 << 9)
#define I2C_SCL_OUT      (1 << 17) /* inverted */
#define I2C_SDA_OUT      (1 << 16) /* inverted */

/* delays */
#define CYCLE_DELAY   10
#define TIMEOUT      (HZ / 2)


static void config_radeon(struct pci_dev *dev);

static unsigned long ioaddr;

static void radeon_dvi_setscl(void *data, int val)
{
   unsigned int r;
   r = readl(ioaddr + RADEON_GPIO_DVI_DDC);
   if(val)
      r &= ~I2C_SCL_OUT;
   else
      r |= I2C_SCL_OUT;
   writel(r, ioaddr + RADEON_GPIO_DVI_DDC);
   readl(ioaddr + RADEON_GPIO_DVI_DDC);   /* flush posted write */
}


static void radeon_dvi_setsda(void *data, int val)
{
   unsigned int r;
   r = readl(ioaddr + RADEON_GPIO_DVI_DDC);
   if(val)
      r &= ~I2C_SDA_OUT;
   else
      r |= I2C_SDA_OUT;
   writel(r, ioaddr + RADEON_GPIO_DVI_DDC);
   readl(ioaddr + RADEON_GPIO_DVI_DDC);   /* flush posted write */
}


static int radeon_dvi_getscl(void *data)
{
   return (0 != (readl(ioaddr + RADEON_GPIO_DVI_DDC) & I2C_SCL_IN));
}


static int radeon_dvi_getsda(void *data)
{
   return (0 != (readl(ioaddr + RADEON_GPIO_DVI_DDC) & I2C_SDA_IN));
}


static void radeon_vga_setscl(void *data, int val)
{
   unsigned int r;
   r = readl(ioaddr + RADEON_GPIO_VGA_DDC);
   if(val)
      r &= ~I2C_SCL_OUT;
   else
      r |= I2C_SCL_OUT;
   writel(r, ioaddr + RADEON_GPIO_VGA_DDC);
   readl(ioaddr + RADEON_GPIO_VGA_DDC);   /* flush posted write */
}


static void radeon_vga_setsda(void *data, int val)
{
   unsigned int r;
   r = readl(ioaddr + RADEON_GPIO_VGA_DDC);
   if(val)
      r &= ~I2C_SDA_OUT;
   else
      r |= I2C_SDA_OUT;
   writel(r, ioaddr + RADEON_GPIO_VGA_DDC);
   readl(ioaddr + RADEON_GPIO_VGA_DDC);   /* flush posted write */
}


static int radeon_vga_getscl(void *data)
{
   return (0 != (readl(ioaddr + RADEON_GPIO_VGA_DDC) & I2C_SCL_IN));
}


static int radeon_vga_getsda(void *data)
{
   return (0 != (readl(ioaddr + RADEON_GPIO_VGA_DDC) & I2C_SDA_IN));
}


/* Configures the chip */

void config_radeon(struct pci_dev *dev)
{
   unsigned int cadr;

   /* map memory */
   cadr = dev->resource[0].start;
   cadr &= PCI_BASE_ADDRESS_MEM_MASK;
   ioaddr = (unsigned long)ioremap_nocache(cadr, 0x0001000);
   if(ioaddr) {
//      writel(0x8160, ioaddr + RADEON_GPIO_DVI_DDC2);
//      writel(0x00000020, ioaddr + RADEON_GPIO_DVI_DDC);
      radeon_dvi_setscl(NULL, 1);
      radeon_dvi_setsda(NULL, 1);
      radeon_vga_setscl(NULL, 1);
      radeon_vga_setsda(NULL, 1);
      printk(KERN_INFO "i2c-radeon.o: Using Radeon at 0x%lx\n", ioaddr);
   }

}


static struct i2c_algo_bit_data radeon_dvi_bit_data = {
   .setsda      = radeon_dvi_setsda,
   .setscl      = radeon_dvi_setscl,
   .getsda      = radeon_dvi_getsda,
   .getscl      = radeon_dvi_getscl,
   .udelay      = CYCLE_DELAY,
   .mdelay      = CYCLE_DELAY,
   .timeout   = TIMEOUT
}
;

static struct i2c_algo_bit_data radeon_vga_bit_data = {
   .setsda      = radeon_vga_setsda,
   .setscl      = radeon_vga_setscl,
   .getsda      = radeon_vga_getsda,
   .getscl      = radeon_vga_getscl,
   .udelay      = CYCLE_DELAY,
   .mdelay      = CYCLE_DELAY,
   .timeout   = TIMEOUT
}
;

static struct i2c_adapter radeon_i2c_adapter = {
   .owner      = THIS_MODULE,
   .name      = "ATI Radeon",
   .id      = I2C_HW_B_SAVG, /* FIXME */
   .algo_data   = &radeon_vga_bit_data,
}
;

static struct pci_device_id radeon_ids[] __devinitdata = {
   {
      .vendor      = 0x1002,
      .device      = 0x4C59,
      .subvendor   = PCI_ANY_ID,
      .subdevice   = PCI_ANY_ID,
   }
,
   { 0 }
};

static int __devinit radeon_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
   config_radeon(dev);
   return i2c_bit_add_bus(&radeon_i2c_adapter);
}


static void __devexit radeon_remove(struct pci_dev *dev)
{
   i2c_bit_del_bus(&radeon_i2c_adapter);
}


static int __init i2c_radeon_init(void)
{
   struct pci_dev *dev;
   const struct pci_device_id *id;

   printk(KERN_DEBUG "i2c-radeon.o init\n");

   pci_for_each_dev(dev) {
      id = pci_match_device(radeon_ids, dev);
      if(id && radeon_probe(dev, id) >= 0)
         return 0;
   }

   return -ENODEV;
}

static void __exit i2c_radeon_exit(void)
{
   radeon_remove(NULL);
   iounmap((void *)ioaddr);
}


MODULE_AUTHOR("Jean Delvare <khali@xxxxxxxxxxxx>");
MODULE_DESCRIPTION("ATI Radeon I2C bus driver");
MODULE_LICENSE("GPL");

module_init(i2c_radeon_init);
module_exit(i2c_radeon_exit);
  Mit Zitat antworten Zitat