iicoc: split up common core and PCI bus specifics
The OpenCores I2C IP core can be found on any bus. Split out the PCI bus specifics into their own file, only compiled on systems with PCI. Reviewed by: kp Sponsored by: Axiado
This commit is contained in:
parent
fe434b6acf
commit
eb95689a82
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=355923
@ -1797,6 +1797,7 @@ dev/iicbus/iiconf.c optional iicbus
|
||||
dev/iicbus/iicsmb.c optional iicsmb \
|
||||
dependency "iicbus_if.h"
|
||||
dev/iicbus/iicoc.c optional iicoc
|
||||
dev/iicbus/iicoc_pci.c optional iicoc pci
|
||||
dev/iicbus/isl12xx.c optional isl12xx
|
||||
dev/iicbus/lm75.c optional lm75
|
||||
dev/iicbus/nxprtc.c optional nxprtc | pcf8563
|
||||
|
@ -45,41 +45,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include "iicbus_if.h"
|
||||
#include "iicoc.h"
|
||||
|
||||
static devclass_t iicoc_devclass;
|
||||
devclass_t iicoc_devclass;
|
||||
|
||||
/*
|
||||
* Device methods
|
||||
*/
|
||||
static int iicoc_probe(device_t);
|
||||
static int iicoc_attach(device_t);
|
||||
static int iicoc_detach(device_t);
|
||||
|
||||
static int iicoc_start(device_t dev, u_char slave, int timeout);
|
||||
static int iicoc_stop(device_t dev);
|
||||
static int iicoc_read(device_t dev, char *buf,
|
||||
int len, int *read, int last, int delay);
|
||||
static int iicoc_write(device_t dev, const char *buf,
|
||||
int len, int *sent, int timeout);
|
||||
static int iicoc_repeated_start(device_t dev, u_char slave, int timeout);
|
||||
|
||||
struct iicoc_softc {
|
||||
device_t dev; /* Self */
|
||||
u_int reg_shift; /* Chip specific */
|
||||
u_int clockfreq;
|
||||
u_int i2cfreq;
|
||||
struct resource *mem_res; /* Memory resource */
|
||||
int mem_rid;
|
||||
int sc_started;
|
||||
uint8_t i2cdev_addr;
|
||||
device_t iicbus;
|
||||
struct mtx sc_mtx;
|
||||
};
|
||||
DRIVER_MODULE(iicbus, iicoc, iicbus_driver, iicbus_devclass, 0, 0);
|
||||
|
||||
static void
|
||||
iicoc_dev_write(device_t dev, int reg, int value)
|
||||
@ -155,7 +126,7 @@ iicoc_wr_ack_cmd(device_t dev, uint8_t data, uint8_t cmd)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
iicoc_init(device_t dev)
|
||||
{
|
||||
struct iicoc_softc *sc;
|
||||
@ -176,70 +147,8 @@ iicoc_init(device_t dev)
|
||||
return ((value & OC_CONTROL_EN) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_probe(device_t dev)
|
||||
{
|
||||
struct iicoc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
if ((pci_get_vendor(dev) == 0x184e) &&
|
||||
(pci_get_device(dev) == 0x1011)) {
|
||||
sc->clockfreq = XLP_I2C_CLKFREQ;
|
||||
sc->i2cfreq = XLP_I2C_FREQ;
|
||||
sc->reg_shift = 2;
|
||||
device_set_desc(dev, "Netlogic XLP I2C Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We add all the devices which we know about.
|
||||
* The generic attach routine will attach them if they are alive.
|
||||
*/
|
||||
static int
|
||||
iicoc_attach(device_t dev)
|
||||
{
|
||||
int bus;
|
||||
struct iicoc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
bus = device_get_unit(dev);
|
||||
|
||||
sc->dev = dev;
|
||||
mtx_init(&sc->sc_mtx, "iicoc", "iicoc", MTX_DEF);
|
||||
sc->mem_rid = 0;
|
||||
sc->mem_res = bus_alloc_resource_anywhere(dev,
|
||||
SYS_RES_MEMORY, &sc->mem_rid, 0x100, RF_ACTIVE);
|
||||
|
||||
if (sc->mem_res == NULL) {
|
||||
device_printf(dev, "Could not allocate bus resource.\n");
|
||||
return (-1);
|
||||
}
|
||||
iicoc_init(dev);
|
||||
sc->iicbus = device_add_child(dev, "iicbus", -1);
|
||||
if (sc->iicbus == NULL) {
|
||||
device_printf(dev, "Could not allocate iicbus instance.\n");
|
||||
return (-1);
|
||||
}
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_detach(device_t dev)
|
||||
{
|
||||
|
||||
bus_generic_detach(dev);
|
||||
device_delete_children(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_start(device_t dev, u_char slave, int timeout)
|
||||
int
|
||||
iicoc_iicbus_start(device_t dev, u_char slave, int timeout)
|
||||
{
|
||||
int error = IIC_EBUSERR;
|
||||
struct iicoc_softc *sc;
|
||||
@ -277,8 +186,8 @@ iicoc_start(device_t dev, u_char slave, int timeout)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_stop(device_t dev)
|
||||
int
|
||||
iicoc_iicbus_stop(device_t dev)
|
||||
{
|
||||
int error = 0;
|
||||
struct iicoc_softc *sc;
|
||||
@ -291,8 +200,9 @@ iicoc_stop(device_t dev)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_write(device_t dev, const char *buf, int len, int *sent, int timeout)
|
||||
int
|
||||
iicoc_iicbus_write(device_t dev, const char *buf, int len, int *sent,
|
||||
int timeout)
|
||||
{
|
||||
uint8_t value;
|
||||
int i;
|
||||
@ -320,8 +230,9 @@ iicoc_write(device_t dev, const char *buf, int len, int *sent, int timeout)
|
||||
return (IIC_EBUSERR);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_read(device_t dev, char *buf, int len, int *read, int last, int delay)
|
||||
int
|
||||
iicoc_iicbus_read(device_t dev, char *buf, int len, int *read, int last,
|
||||
int delay)
|
||||
{
|
||||
int data, i;
|
||||
uint8_t cmd;
|
||||
@ -345,8 +256,8 @@ iicoc_read(device_t dev, char *buf, int len, int *read, int last, int delay)
|
||||
return (IIC_EBUSERR);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
|
||||
int
|
||||
iicoc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
|
||||
{
|
||||
int error;
|
||||
struct iicoc_softc *sc;
|
||||
@ -358,37 +269,9 @@ iicoc_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_repeated_start(device_t dev, u_char slave, int timeout)
|
||||
int
|
||||
iicoc_iicbus_repeated_start(device_t dev, u_char slave, int timeout)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static device_method_t iicoc_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, iicoc_probe),
|
||||
DEVMETHOD(device_attach, iicoc_attach),
|
||||
DEVMETHOD(device_detach, iicoc_detach),
|
||||
|
||||
/* iicbus interface */
|
||||
DEVMETHOD(iicbus_callback, iicbus_null_callback),
|
||||
DEVMETHOD(iicbus_repeated_start, iicoc_repeated_start),
|
||||
DEVMETHOD(iicbus_start, iicoc_start),
|
||||
DEVMETHOD(iicbus_stop, iicoc_stop),
|
||||
DEVMETHOD(iicbus_reset, iicoc_reset),
|
||||
DEVMETHOD(iicbus_write, iicoc_write),
|
||||
DEVMETHOD(iicbus_read, iicoc_read),
|
||||
DEVMETHOD(iicbus_transfer, iicbus_transfer_gen),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t iicoc_driver = {
|
||||
"iicoc",
|
||||
iicoc_methods,
|
||||
sizeof(struct iicoc_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(iicoc, pci, iicoc_driver, iicoc_devclass, 0, 0);
|
||||
DRIVER_MODULE(iicbus, iicoc, iicbus_driver, iicbus_devclass, 0, 0);
|
||||
|
@ -77,4 +77,30 @@
|
||||
#define OC_STATUS_TIP 0x02 /* Transfer in Progress */
|
||||
#define OC_STATUS_IF 0x01 /* Intr. Pending Flag */
|
||||
|
||||
struct iicoc_softc {
|
||||
device_t dev; /* Self */
|
||||
u_int reg_shift; /* Chip specific */
|
||||
u_int clockfreq;
|
||||
u_int i2cfreq;
|
||||
struct resource *mem_res; /* Memory resource */
|
||||
int mem_rid;
|
||||
int sc_started;
|
||||
uint8_t i2cdev_addr;
|
||||
device_t iicbus;
|
||||
struct mtx sc_mtx;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
extern devclass_t iicoc_devclass;
|
||||
|
||||
int iicoc_iicbus_start(device_t dev, u_char slave, int timeout);
|
||||
int iicoc_iicbus_stop(device_t dev);
|
||||
int iicoc_iicbus_read(device_t dev, char *buf, int len, int *read, int last,
|
||||
int delay);
|
||||
int iicoc_iicbus_write(device_t dev, const char *buf, int len, int *sent,
|
||||
int timeout);
|
||||
int iicoc_iicbus_repeated_start(device_t dev, u_char slave, int timeout);
|
||||
int iicoc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr);
|
||||
|
||||
int iicoc_init(device_t dev);
|
||||
|
143
sys/dev/iicbus/iicoc_pci.c
Normal file
143
sys/dev/iicbus/iicoc_pci.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2003-2012 Broadcom Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include "iicbus_if.h"
|
||||
#include "iicoc.h"
|
||||
|
||||
static int
|
||||
iicoc_detach(device_t dev)
|
||||
{
|
||||
struct iicoc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
device_delete_children(dev);
|
||||
bus_generic_detach(dev);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, &sc->mem_res);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We add all the devices which we know about.
|
||||
* The generic attach routine will attach them if they are alive.
|
||||
*/
|
||||
static int
|
||||
iicoc_attach(device_t dev)
|
||||
{
|
||||
int bus;
|
||||
struct iicoc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
bus = device_get_unit(dev);
|
||||
|
||||
sc->dev = dev;
|
||||
mtx_init(&sc->sc_mtx, "iicoc", "iicoc", MTX_DEF);
|
||||
sc->mem_rid = 0;
|
||||
sc->mem_res = bus_alloc_resource_anywhere(dev,
|
||||
SYS_RES_MEMORY, &sc->mem_rid, 0x100, RF_ACTIVE);
|
||||
|
||||
if (sc->mem_res == NULL) {
|
||||
device_printf(dev, "Could not allocate bus resource.\n");
|
||||
return (-1);
|
||||
}
|
||||
iicoc_init(dev);
|
||||
sc->iicbus = device_add_child(dev, "iicbus", -1);
|
||||
if (sc->iicbus == NULL) {
|
||||
device_printf(dev, "Could not allocate iicbus instance.\n");
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
|
||||
&sc->mem_res);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return (-1);
|
||||
}
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicoc_probe(device_t dev)
|
||||
{
|
||||
struct iicoc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
if ((pci_get_vendor(dev) == 0x184e) &&
|
||||
(pci_get_device(dev) == 0x1011)) {
|
||||
sc->clockfreq = XLP_I2C_CLKFREQ;
|
||||
sc->i2cfreq = XLP_I2C_FREQ;
|
||||
sc->reg_shift = 2;
|
||||
device_set_desc(dev, "Netlogic XLP I2C Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static device_method_t iicoc_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, iicoc_probe),
|
||||
DEVMETHOD(device_attach, iicoc_attach),
|
||||
DEVMETHOD(device_detach, iicoc_detach),
|
||||
|
||||
/* iicbus interface */
|
||||
DEVMETHOD(iicbus_callback, iicbus_null_callback),
|
||||
DEVMETHOD(iicbus_repeated_start, iicoc_iicbus_repeated_start),
|
||||
DEVMETHOD(iicbus_start, iicoc_iicbus_start),
|
||||
DEVMETHOD(iicbus_stop, iicoc_iicbus_stop),
|
||||
DEVMETHOD(iicbus_reset, iicoc_iicbus_reset),
|
||||
DEVMETHOD(iicbus_write, iicoc_iicbus_write),
|
||||
DEVMETHOD(iicbus_read, iicoc_iicbus_read),
|
||||
DEVMETHOD(iicbus_transfer, iicbus_transfer_gen),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t iicoc_driver = {
|
||||
"iicoc",
|
||||
iicoc_methods,
|
||||
sizeof(struct iicoc_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(iicoc, pci, iicoc_driver, iicoc_devclass, 0, 0);
|
Loading…
Reference in New Issue
Block a user