Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/w1/masters/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  matrox_w1.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * matrox_w1.c
 *
 * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
 */


#include <asm/types.h>
#include <linux/atomic.h>
#include <linux/io.h>

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/pci_ids.h>
#include <linux/pci.h>

#include <linux/w1.h>

/*
 * Matrox G400 DDC registers.
 */


#define MATROX_G400_DDC_CLK  (1<<4)
#define MATROX_G400_DDC_DATA  (1<<1)

#define MATROX_BASE   0x3C00
#define MATROX_STATUS   0x1e14

#define MATROX_PORT_INDEX_OFFSET 0x00
#define MATROX_PORT_DATA_OFFSET  0x0A

#define MATROX_GET_CONTROL  0x2A
#define MATROX_GET_DATA   0x2B
#define MATROX_CURSOR_CTL  0x06

struct matrox_device {
 void __iomem *base_addr;
 void __iomem *port_index;
 void __iomem *port_data;
 u8 data_mask;

 unsigned long phys_addr;
 void __iomem *virt_addr;
 unsigned long found;

 struct w1_bus_master *bus_master;
};

/*
 * These functions read and write DDC Data bit.
 *
 * Using tristate pins, since i can't find any open-drain pin in whole motherboard.
 * Unfortunately we can't connect to Intel's 82801xx IO controller
 * since we don't know motherboard schema, which has pretty unused(may be not) GPIO.
 *
 * I've heard that PIIX also has open drain pin.
 *
 * Port mapping.
 */

static inline u8 matrox_w1_read_reg(struct matrox_device *dev, u8 reg)
{
 u8 ret;

 writeb(reg, dev->port_index);
 ret = readb(dev->port_data);
 barrier();

 return ret;
}

static inline void matrox_w1_write_reg(struct matrox_device *dev, u8 reg, u8 val)
{
 writeb(reg, dev->port_index);
 writeb(val, dev->port_data);
 wmb();
}

static void matrox_w1_write_ddc_bit(void *data, u8 bit)
{
 u8 ret;
 struct matrox_device *dev = data;

 if (bit)
  bit = 0;
 else
  bit = dev->data_mask;

 ret = matrox_w1_read_reg(dev, MATROX_GET_CONTROL);
 matrox_w1_write_reg(dev, MATROX_GET_CONTROL, ((ret & ~dev->data_mask) | bit));
 matrox_w1_write_reg(dev, MATROX_GET_DATA, 0x00);
}

static u8 matrox_w1_read_ddc_bit(void *data)
{
 u8 ret;
 struct matrox_device *dev = data;

 ret = matrox_w1_read_reg(dev, MATROX_GET_DATA);

 return ret;
}

static void matrox_w1_hw_init(struct matrox_device *dev)
{
 matrox_w1_write_reg(dev, MATROX_GET_DATA, 0xFF);
 matrox_w1_write_reg(dev, MATROX_GET_CONTROL, 0x00);
}

static int matrox_w1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
 struct matrox_device *dev;
 int err;

 if (pdev->vendor != PCI_VENDOR_ID_MATROX || pdev->device != PCI_DEVICE_ID_MATROX_G400)
  return -ENODEV;

 dev = kzalloc(sizeof(struct matrox_device) +
         sizeof(struct w1_bus_master), GFP_KERNEL);
 if (!dev)
  return -ENOMEM;

 dev->bus_master = (struct w1_bus_master *)(dev + 1);

 /*
 * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c
 */


 dev->phys_addr = pci_resource_start(pdev, 1);

 dev->virt_addr = ioremap(dev->phys_addr, 16384);
 if (!dev->virt_addr) {
  dev_err(&pdev->dev, "%s: failed to ioremap(0x%lx, %d).\n",
   __func__, dev->phys_addr, 16384);
  err = -EIO;
  goto err_out_free_device;
 }

 dev->base_addr = dev->virt_addr + MATROX_BASE;
 dev->port_index = dev->base_addr + MATROX_PORT_INDEX_OFFSET;
 dev->port_data = dev->base_addr + MATROX_PORT_DATA_OFFSET;
 dev->data_mask = (MATROX_G400_DDC_DATA);

 matrox_w1_hw_init(dev);

 dev->bus_master->data = dev;
 dev->bus_master->read_bit = &matrox_w1_read_ddc_bit;
 dev->bus_master->write_bit = &matrox_w1_write_ddc_bit;

 err = w1_add_master_device(dev->bus_master);
 if (err)
  goto err_out_free_device;

 pci_set_drvdata(pdev, dev);

 dev->found = 1;

 dev_info(&pdev->dev, "Matrox G400 GPIO transport layer for 1-wire.\n");

 return 0;

err_out_free_device:
 if (dev->virt_addr)
  iounmap(dev->virt_addr);
 kfree(dev);

 return err;
}

static void matrox_w1_remove(struct pci_dev *pdev)
{
 struct matrox_device *dev = pci_get_drvdata(pdev);

 if (dev->found) {
  w1_remove_master_device(dev->bus_master);
  iounmap(dev->virt_addr);
 }
 kfree(dev);
}

static struct pci_device_id matrox_w1_tbl[] = {
 { PCI_DEVICE(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400) },
 { },
};
MODULE_DEVICE_TABLE(pci, matrox_w1_tbl);

static struct pci_driver matrox_w1_pci_driver = {
 .name = "matrox_w1",
 .id_table = matrox_w1_tbl,
 .probe = matrox_w1_probe,
 .remove = matrox_w1_remove,
};
module_pci_driver(matrox_w1_pci_driver);

MODULE_AUTHOR("Evgeniy Polyakov ");
MODULE_DESCRIPTION("Driver for transport(Dallas 1-wire protocol) over VGA DDC(matrox gpio).");
MODULE_LICENSE("GPL");

Messung V0.5
C=97 H=92 G=94

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.