ixp425_iic.c revision 164426
1164426Ssam/* 2164426Ssam * Copyright (c) 2006 Kevin Lo. All rights reserved. 3164426Ssam * 4164426Ssam * Redistribution and use in source and binary forms, with or without 5164426Ssam * modification, are permitted provided that the following conditions 6164426Ssam * are met: 7164426Ssam * 1. Redistributions of source code must retain the above copyright 8164426Ssam * notice, this list of conditions and the following disclaimer. 9164426Ssam * 2. Redistributions in binary form must reproduce the above copyright 10164426Ssam * notice, this list of conditions and the following disclaimer in the 11164426Ssam * documentation and/or other materials provided with the distribution. 12164426Ssam * 3. All advertising materials mentioning features or use of this software 13164426Ssam * must display the following acknowledgement: 14164426Ssam * This product includes software developed for the NetBSD Project by 15164426Ssam * Wasabi Systems, Inc. 16164426Ssam * 4. The name of Wasabi Systems, Inc. may not be used to endorse 17164426Ssam * or promote products derived from this software without specific prior 18164426Ssam * written permission. 19164426Ssam * 20164426Ssam * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 21164426Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22164426Ssam * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23164426Ssam * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 24164426Ssam * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25164426Ssam * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26164426Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27164426Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28164426Ssam * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29164426Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30164426Ssam * POSSIBILITY OF SUCH DAMAGE. 31164426Ssam */ 32164426Ssam 33164426Ssam#include <sys/cdefs.h> 34164426Ssam__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/ixp425_iic.c 164426 2006-11-19 23:55:23Z sam $"); 35164426Ssam 36164426Ssam#include <sys/param.h> 37164426Ssam#include <sys/systm.h> 38164426Ssam#include <sys/kernel.h> 39164426Ssam#include <sys/module.h> 40164426Ssam#include <sys/bus.h> 41164426Ssam#include <sys/uio.h> 42164426Ssam 43164426Ssam#include <arm/xscale/ixp425/ixp425reg.h> 44164426Ssam#include <arm/xscale/ixp425/ixp425var.h> 45164426Ssam#include <arm/xscale/ixp425/ixdp425reg.h> 46164426Ssam 47164426Ssam#include <dev/iicbus/iiconf.h> 48164426Ssam#include <dev/iicbus/iicbus.h> 49164426Ssam 50164426Ssam#include "iicbb_if.h" 51164426Ssam 52164426Ssam#define I2C_DELAY 10 53164426Ssam 54164426Ssam/* bit clr/set shorthands */ 55164426Ssam#define GPIO_CONF_CLR(sc, reg, mask) \ 56164426Ssam GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) &~ (mask)) 57164426Ssam#define GPIO_CONF_SET(sc, reg, mask) \ 58164426Ssam GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) | (mask)) 59164426Ssam 60164426Ssamstruct ixpiic_softc { 61164426Ssam device_t sc_dev; 62164426Ssam bus_space_tag_t sc_iot; 63164426Ssam bus_space_handle_t sc_gpio_ioh; 64164426Ssam 65164426Ssam device_t iicbb; 66164426Ssam}; 67164426Ssam 68164426Ssamstatic struct ixpiic_softc *ixpiic_sc = NULL; 69164426Ssam 70164426Ssamstatic int 71164426Ssamixpiic_probe(device_t dev) 72164426Ssam{ 73164426Ssam device_set_desc(dev, "IXP425 GPIO-Based I2C Interface"); 74164426Ssam return (0); 75164426Ssam} 76164426Ssam 77164426Ssamstatic int 78164426Ssamixpiic_attach(device_t dev) 79164426Ssam{ 80164426Ssam struct ixpiic_softc *sc = device_get_softc(dev); 81164426Ssam struct ixp425_softc *sa = device_get_softc(device_get_parent(dev)); 82164426Ssam 83164426Ssam ixpiic_sc = sc; 84164426Ssam 85164426Ssam sc->sc_dev = dev; 86164426Ssam sc->sc_iot = sa->sc_iot; 87164426Ssam sc->sc_gpio_ioh = sa->sc_gpio_ioh; 88164426Ssam 89164426Ssam GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, 90164426Ssam GPIO_I2C_SCL_BIT | GPIO_I2C_SDA_BIT); 91164426Ssam GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, 92164426Ssam GPIO_I2C_SCL_BIT | GPIO_I2C_SDA_BIT); 93164426Ssam 94164426Ssam /* add generic bit-banging code */ 95164426Ssam if ((sc->iicbb = device_add_child(dev, "iicbb", -1)) == NULL) 96164426Ssam device_printf(dev, "could not add iicbb\n"); 97164426Ssam 98164426Ssam /* probe and attach the bit-banging code */ 99164426Ssam device_probe_and_attach(sc->iicbb); 100164426Ssam 101164426Ssam return (0); 102164426Ssam} 103164426Ssam 104164426Ssamstatic int 105164426Ssamixpiic_callback(device_t dev, int index, caddr_t *data) 106164426Ssam{ 107164426Ssam return (0); 108164426Ssam} 109164426Ssam 110164426Ssamstatic int 111164426Ssamixpiic_getscl(device_t dev) 112164426Ssam{ 113164426Ssam struct ixpiic_softc *sc = ixpiic_sc; 114164426Ssam uint32_t reg; 115164426Ssam 116164426Ssam GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); 117164426Ssam 118164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); 119164426Ssam return (reg & GPIO_I2C_SCL_BIT); 120164426Ssam} 121164426Ssam 122164426Ssamstatic int 123164426Ssamixpiic_getsda(device_t dev) 124164426Ssam{ 125164426Ssam struct ixpiic_softc *sc = ixpiic_sc; 126164426Ssam uint32_t reg; 127164426Ssam 128164426Ssam GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); 129164426Ssam 130164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); 131164426Ssam return (reg & GPIO_I2C_SDA_BIT); 132164426Ssam} 133164426Ssam 134164426Ssamstatic void 135164426Ssamixpiic_setsda(device_t dev, char val) 136164426Ssam{ 137164426Ssam struct ixpiic_softc *sc = ixpiic_sc; 138164426Ssam 139164426Ssam GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT); 140164426Ssam if (val) 141164426Ssam GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); 142164426Ssam else 143164426Ssam GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); 144164426Ssam DELAY(I2C_DELAY); 145164426Ssam} 146164426Ssam 147164426Ssamstatic void 148164426Ssamixpiic_setscl(device_t dev, char val) 149164426Ssam{ 150164426Ssam struct ixpiic_softc *sc = ixpiic_sc; 151164426Ssam 152164426Ssam GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT); 153164426Ssam if (val) 154164426Ssam GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); 155164426Ssam else 156164426Ssam GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); 157164426Ssam DELAY(I2C_DELAY); 158164426Ssam} 159164426Ssam 160164426Ssamstatic int 161164426Ssamixpiic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 162164426Ssam{ 163164426Ssam /* reset bus */ 164164426Ssam ixpiic_setsda(dev, 1); 165164426Ssam ixpiic_setscl(dev, 1); 166164426Ssam 167164426Ssam return (IIC_ENOADDR); 168164426Ssam} 169164426Ssam 170164426Ssamstatic device_method_t ixpiic_methods[] = { 171164426Ssam /* device interface */ 172164426Ssam DEVMETHOD(device_probe, ixpiic_probe), 173164426Ssam DEVMETHOD(device_attach, ixpiic_attach), 174164426Ssam 175164426Ssam /* iicbb interface */ 176164426Ssam DEVMETHOD(iicbb_callback, ixpiic_callback), 177164426Ssam DEVMETHOD(iicbb_setsda, ixpiic_setsda), 178164426Ssam DEVMETHOD(iicbb_setscl, ixpiic_setscl), 179164426Ssam DEVMETHOD(iicbb_getsda, ixpiic_getsda), 180164426Ssam DEVMETHOD(iicbb_getscl, ixpiic_getscl), 181164426Ssam DEVMETHOD(iicbb_reset, ixpiic_reset), 182164426Ssam 183164426Ssam { 0, 0 } 184164426Ssam}; 185164426Ssam 186164426Ssamstatic driver_t ixpiic_driver = { 187164426Ssam "ixpiic", 188164426Ssam ixpiic_methods, 189164426Ssam sizeof(struct ixpiic_softc), 190164426Ssam}; 191164426Ssamstatic devclass_t ixpiic_devclass; 192164426Ssam 193164426SsamDRIVER_MODULE(ixpiic, ixp, ixpiic_driver, ixpiic_devclass, 0, 0); 194