Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/ti/ti_i2c.c
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include <arm/ti/ti_cpuid.h> | #include <arm/ti/ti_cpuid.h> | ||||
#include <arm/ti/ti_prcm.h> | #include <arm/ti/ti_sysc.h> | ||||
#include <arm/ti/ti_hwmods.h> | |||||
#include <arm/ti/ti_i2c.h> | #include <arm/ti/ti_i2c.h> | ||||
#include <dev/iicbus/iiconf.h> | #include <dev/iicbus/iiconf.h> | ||||
#include <dev/iicbus/iicbus.h> | #include <dev/iicbus/iicbus.h> | ||||
#include "iicbus_if.h" | #include "iicbus_if.h" | ||||
/** | /** | ||||
* I2C device driver context, a pointer to this is stored in the device | * I2C device driver context, a pointer to this is stored in the device | ||||
* driver structure. | * driver structure. | ||||
*/ | */ | ||||
struct ti_i2c_softc | struct ti_i2c_softc | ||||
{ | { | ||||
device_t sc_dev; | device_t sc_dev; | ||||
clk_ident_t clk_id; | |||||
struct resource* sc_irq_res; | struct resource* sc_irq_res; | ||||
struct resource* sc_mem_res; | struct resource* sc_mem_res; | ||||
device_t sc_iicbus; | device_t sc_iicbus; | ||||
void* sc_irq_h; | void* sc_irq_h; | ||||
struct mtx sc_mtx; | struct mtx sc_mtx; | ||||
▲ Show 20 Lines • Show All 604 Lines • ▼ Show 20 Lines | ti_i2c_activate(device_t dev) | ||||
struct ti_i2c_softc *sc; | struct ti_i2c_softc *sc; | ||||
sc = (struct ti_i2c_softc*)device_get_softc(dev); | sc = (struct ti_i2c_softc*)device_get_softc(dev); | ||||
/* | /* | ||||
* 1. Enable the functional and interface clocks (see Section | * 1. Enable the functional and interface clocks (see Section | ||||
* 23.1.5.1.1.1.1). | * 23.1.5.1.1.1.1). | ||||
*/ | */ | ||||
err = ti_prcm_clk_enable(sc->clk_id); | err = ti_sysc_clock_enable(device_get_parent(dev)); | ||||
if (err) | if (err) | ||||
return (err); | return (err); | ||||
return (ti_i2c_reset(sc, IIC_UNKNOWN)); | return (ti_i2c_reset(sc, IIC_UNKNOWN)); | ||||
} | } | ||||
/** | /** | ||||
* ti_i2c_deactivate - deactivates the controller and releases resources | * ti_i2c_deactivate - deactivates the controller and releases resources | ||||
Show All 31 Lines | ti_i2c_deactivate(device_t dev) | ||||
/* Release the IRQ resource. */ | /* Release the IRQ resource. */ | ||||
if (sc->sc_irq_res != NULL) { | if (sc->sc_irq_res != NULL) { | ||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); | bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); | ||||
sc->sc_irq_res = NULL; | sc->sc_irq_res = NULL; | ||||
} | } | ||||
/* Finally disable the functional and interface clocks. */ | /* Finally disable the functional and interface clocks. */ | ||||
ti_prcm_clk_disable(sc->clk_id); | ti_sysc_clock_disable(device_get_parent(dev)); | ||||
} | } | ||||
static int | static int | ||||
ti_i2c_sysctl_clk(SYSCTL_HANDLER_ARGS) | ti_i2c_sysctl_clk(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int clk, psc, sclh, scll; | int clk, psc, sclh, scll; | ||||
struct ti_i2c_softc *sc; | struct ti_i2c_softc *sc; | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | ti_i2c_probe(device_t dev) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
ti_i2c_attach(device_t dev) | ti_i2c_attach(device_t dev) | ||||
{ | { | ||||
int err, rid; | int err, rid; | ||||
phandle_t node; | |||||
struct ti_i2c_softc *sc; | struct ti_i2c_softc *sc; | ||||
struct sysctl_ctx_list *ctx; | struct sysctl_ctx_list *ctx; | ||||
struct sysctl_oid_list *tree; | struct sysctl_oid_list *tree; | ||||
uint16_t fifosz; | uint16_t fifosz; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
sc->sc_dev = dev; | sc->sc_dev = dev; | ||||
/* Get the i2c device id from FDT. */ | |||||
node = ofw_bus_get_node(dev); | |||||
/* i2c ti,hwmods bindings is special: it start with index 1 */ | |||||
sc->clk_id = ti_hwmods_get_clock(dev); | |||||
if (sc->clk_id == INVALID_CLK_IDENT) { | |||||
device_printf(dev, "failed to get device id using ti,hwmod\n"); | |||||
return (ENXIO); | |||||
} | |||||
/* Get the memory resource for the register mapping. */ | /* Get the memory resource for the register mapping. */ | ||||
rid = 0; | rid = 0; | ||||
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, | sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, | ||||
RF_ACTIVE); | RF_ACTIVE); | ||||
if (sc->sc_mem_res == NULL) { | if (sc->sc_mem_res == NULL) { | ||||
device_printf(dev, "Cannot map registers.\n"); | device_printf(dev, "Cannot map registers.\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | static driver_t ti_i2c_driver = { | ||||
sizeof(struct ti_i2c_softc), | sizeof(struct ti_i2c_softc), | ||||
}; | }; | ||||
static devclass_t ti_i2c_devclass; | static devclass_t ti_i2c_devclass; | ||||
DRIVER_MODULE(ti_iic, simplebus, ti_i2c_driver, ti_i2c_devclass, 0, 0); | DRIVER_MODULE(ti_iic, simplebus, ti_i2c_driver, ti_i2c_devclass, 0, 0); | ||||
DRIVER_MODULE(iicbus, ti_iic, iicbus_driver, iicbus_devclass, 0, 0); | DRIVER_MODULE(iicbus, ti_iic, iicbus_driver, iicbus_devclass, 0, 0); | ||||
MODULE_DEPEND(ti_iic, ti_prcm, 1, 1, 1); | MODULE_DEPEND(ti_iic, ti_sysc, 1, 1, 1); | ||||
MODULE_DEPEND(ti_iic, iicbus, 1, 1, 1); | MODULE_DEPEND(ti_iic, iicbus, 1, 1, 1); |