1/*- 2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of MARVELL nor the names of contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32/* 33 * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell 34 * SoCs. Supports master operation only, and works in polling mode. 35 * 36 * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software 37 * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices". 38 */ 39 40#include <sys/cdefs.h>
| 1/*- 2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of MARVELL nor the names of contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32/* 33 * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell 34 * SoCs. Supports master operation only, and works in polling mode. 35 * 36 * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software 37 * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices". 38 */ 39 40#include <sys/cdefs.h>
|
41__FBSDID("$FreeBSD: stable/10/sys/arm/mv/twsi.c 239508 2012-08-21 17:49:20Z hrs $");
| 41__FBSDID("$FreeBSD: stable/10/sys/arm/mv/twsi.c 266152 2014-05-15 16:11:06Z ian $");
|
42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/bus.h> 46#include <sys/kernel.h> 47#include <sys/module.h> 48#include <sys/resource.h> 49 50#include <machine/_inttypes.h> 51#include <machine/bus.h> 52#include <machine/resource.h> 53 54#include <sys/rman.h> 55 56#include <sys/lock.h> 57#include <sys/mutex.h> 58 59#include <dev/iicbus/iiconf.h> 60#include <dev/iicbus/iicbus.h> 61#include <dev/fdt/fdt_common.h> 62#include <dev/ofw/ofw_bus.h> 63#include <dev/ofw/ofw_bus_subr.h> 64 65#include <arm/mv/mvreg.h> 66#include <arm/mv/mvvar.h> 67 68#include "iicbus_if.h" 69 70#define MV_TWSI_NAME "twsi" 71#define IICBUS_DEVNAME "iicbus" 72 73#define TWSI_SLAVE_ADDR 0x00 74#define TWSI_EXT_SLAVE_ADDR 0x10 75#define TWSI_DATA 0x04 76 77#define TWSI_CONTROL 0x08 78#define TWSI_CONTROL_ACK (1 << 2) 79#define TWSI_CONTROL_IFLG (1 << 3) 80#define TWSI_CONTROL_STOP (1 << 4) 81#define TWSI_CONTROL_START (1 << 5) 82#define TWSI_CONTROL_TWSIEN (1 << 6) 83#define TWSI_CONTROL_INTEN (1 << 7) 84 85#define TWSI_STATUS 0x0c 86#define TWSI_STATUS_START 0x08 87#define TWSI_STATUS_RPTD_START 0x10 88#define TWSI_STATUS_ADDR_W_ACK 0x18 89#define TWSI_STATUS_DATA_WR_ACK 0x28 90#define TWSI_STATUS_ADDR_R_ACK 0x40 91#define TWSI_STATUS_DATA_RD_ACK 0x50 92#define TWSI_STATUS_DATA_RD_NOACK 0x58 93 94#define TWSI_BAUD_RATE 0x0c 95#define TWSI_BAUD_RATE_PARAM(M,N) ((((M) << 3) | ((N) & 0x7)) & 0x7f) 96#define TWSI_BAUD_RATE_RAW(C,M,N) ((C)/((10*(M+1))<<(N+1))) 97#define TWSI_BAUD_RATE_SLOW 50000 /* 50kHz */ 98#define TWSI_BAUD_RATE_FAST 100000 /* 100kHz */ 99 100#define TWSI_SOFT_RESET 0x1c 101 102#define TWSI_DEBUG 103#undef TWSI_DEBUG 104 105#ifdef TWSI_DEBUG 106#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0) 107#else 108#define debugf(fmt, args...) 109#endif 110 111struct mv_twsi_softc { 112 device_t dev; 113 struct resource *res[1]; /* SYS_RES_MEMORY */ 114 struct mtx mutex; 115 device_t iicbus; 116}; 117 118static struct mv_twsi_baud_rate { 119 uint32_t raw; 120 int param; 121 int m; 122 int n; 123} baud_rate[IIC_FASTEST + 1]; 124 125static int mv_twsi_probe(device_t); 126static int mv_twsi_attach(device_t); 127static int mv_twsi_detach(device_t); 128 129static int mv_twsi_reset(device_t dev, u_char speed, u_char addr, 130 u_char *oldaddr); 131static int mv_twsi_repeated_start(device_t dev, u_char slave, int timeout); 132static int mv_twsi_start(device_t dev, u_char slave, int timeout); 133static int mv_twsi_stop(device_t dev); 134static int mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, 135 int delay); 136static int mv_twsi_write(device_t dev, const char *buf, int len, int *sent, 137 int timeout); 138 139static struct resource_spec res_spec[] = { 140 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 141 { -1, 0 } 142}; 143 144static device_method_t mv_twsi_methods[] = { 145 /* device interface */ 146 DEVMETHOD(device_probe, mv_twsi_probe), 147 DEVMETHOD(device_attach, mv_twsi_attach), 148 DEVMETHOD(device_detach, mv_twsi_detach), 149 150 /* iicbus interface */ 151 DEVMETHOD(iicbus_callback, iicbus_null_callback), 152 DEVMETHOD(iicbus_repeated_start, mv_twsi_repeated_start), 153 DEVMETHOD(iicbus_start, mv_twsi_start), 154 DEVMETHOD(iicbus_stop, mv_twsi_stop), 155 DEVMETHOD(iicbus_write, mv_twsi_write), 156 DEVMETHOD(iicbus_read, mv_twsi_read), 157 DEVMETHOD(iicbus_reset, mv_twsi_reset), 158 DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 159 { 0, 0 } 160}; 161 162static devclass_t mv_twsi_devclass; 163 164static driver_t mv_twsi_driver = { 165 MV_TWSI_NAME, 166 mv_twsi_methods, 167 sizeof(struct mv_twsi_softc), 168}; 169 170DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0); 171DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0); 172MODULE_DEPEND(twsi, iicbus, 1, 1, 1); 173 174static __inline uint32_t 175TWSI_READ(struct mv_twsi_softc *sc, bus_size_t off) 176{ 177 178 return (bus_read_4(sc->res[0], off)); 179} 180 181static __inline void 182TWSI_WRITE(struct mv_twsi_softc *sc, bus_size_t off, uint32_t val) 183{ 184 185 bus_write_4(sc->res[0], off, val); 186} 187 188static __inline void 189twsi_control_clear(struct mv_twsi_softc *sc, uint32_t mask) 190{ 191 uint32_t val; 192 193 val = TWSI_READ(sc, TWSI_CONTROL); 194 val &= ~mask; 195 TWSI_WRITE(sc, TWSI_CONTROL, val); 196} 197 198static __inline void 199twsi_control_set(struct mv_twsi_softc *sc, uint32_t mask) 200{ 201 uint32_t val; 202 203 val = TWSI_READ(sc, TWSI_CONTROL); 204 val |= mask; 205 TWSI_WRITE(sc, TWSI_CONTROL, val); 206} 207 208static __inline void 209twsi_clear_iflg(struct mv_twsi_softc *sc) 210{ 211 212 DELAY(1000); 213 twsi_control_clear(sc, TWSI_CONTROL_IFLG); 214 DELAY(1000); 215} 216 217 218/* 219 * timeout given in us 220 * returns 221 * 0 on sucessfull mask change 222 * non-zero on timeout 223 */ 224static int 225twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask) 226{ 227 228 timeout /= 10; 229 while (!(TWSI_READ(sc, TWSI_CONTROL) & mask)) { 230 DELAY(10); 231 if (--timeout < 0) 232 return (timeout); 233 } 234 return (0); 235} 236 237 238/* 239 * 'timeout' is given in us. Note also that timeout handling is not exact -- 240 * twsi_locked_start() total wait can be more than 2 x timeout 241 * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START 242 * or TWSI_STATUS_RPTD_START 243 */ 244static int 245twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, 246 u_char slave, int timeout) 247{ 248 int read_access, iflg_set = 0; 249 uint32_t status; 250 251 mtx_assert(&sc->mutex, MA_OWNED); 252 253 if (mask == TWSI_STATUS_RPTD_START) 254 /* read IFLG to know if it should be cleared later; from NBSD */ 255 iflg_set = TWSI_READ(sc, TWSI_CONTROL) & TWSI_CONTROL_IFLG; 256 257 twsi_control_set(sc, TWSI_CONTROL_START); 258 259 if (mask == TWSI_STATUS_RPTD_START && iflg_set) { 260 debugf("IFLG set, clearing\n"); 261 twsi_clear_iflg(sc); 262 } 263 264 /* 265 * Without this delay we timeout checking IFLG if the timeout is 0. 266 * NBSD driver always waits here too. 267 */ 268 DELAY(1000); 269 270 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 271 debugf("timeout sending %sSTART condition\n", 272 mask == TWSI_STATUS_START ? "" : "repeated "); 273 return (IIC_ETIMEOUT); 274 } 275 276 status = TWSI_READ(sc, TWSI_STATUS); 277 if (status != mask) { 278 debugf("wrong status (%02x) after sending %sSTART condition\n", 279 status, mask == TWSI_STATUS_START ? "" : "repeated "); 280 return (IIC_ESTATUS); 281 } 282 283 TWSI_WRITE(sc, TWSI_DATA, slave); 284 DELAY(1000); 285 twsi_clear_iflg(sc); 286 287 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 288 debugf("timeout sending slave address\n"); 289 return (IIC_ETIMEOUT); 290 } 291 292 read_access = (slave & 0x1) ? 1 : 0; 293 status = TWSI_READ(sc, TWSI_STATUS); 294 if (status != (read_access ? 295 TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) { 296 debugf("no ACK (status: %02x) after sending slave address\n", 297 status); 298 return (IIC_ENOACK); 299 } 300 301 return (IIC_NOERR); 302} 303 304static int 305mv_twsi_probe(device_t dev) 306{ 307
| 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/bus.h> 46#include <sys/kernel.h> 47#include <sys/module.h> 48#include <sys/resource.h> 49 50#include <machine/_inttypes.h> 51#include <machine/bus.h> 52#include <machine/resource.h> 53 54#include <sys/rman.h> 55 56#include <sys/lock.h> 57#include <sys/mutex.h> 58 59#include <dev/iicbus/iiconf.h> 60#include <dev/iicbus/iicbus.h> 61#include <dev/fdt/fdt_common.h> 62#include <dev/ofw/ofw_bus.h> 63#include <dev/ofw/ofw_bus_subr.h> 64 65#include <arm/mv/mvreg.h> 66#include <arm/mv/mvvar.h> 67 68#include "iicbus_if.h" 69 70#define MV_TWSI_NAME "twsi" 71#define IICBUS_DEVNAME "iicbus" 72 73#define TWSI_SLAVE_ADDR 0x00 74#define TWSI_EXT_SLAVE_ADDR 0x10 75#define TWSI_DATA 0x04 76 77#define TWSI_CONTROL 0x08 78#define TWSI_CONTROL_ACK (1 << 2) 79#define TWSI_CONTROL_IFLG (1 << 3) 80#define TWSI_CONTROL_STOP (1 << 4) 81#define TWSI_CONTROL_START (1 << 5) 82#define TWSI_CONTROL_TWSIEN (1 << 6) 83#define TWSI_CONTROL_INTEN (1 << 7) 84 85#define TWSI_STATUS 0x0c 86#define TWSI_STATUS_START 0x08 87#define TWSI_STATUS_RPTD_START 0x10 88#define TWSI_STATUS_ADDR_W_ACK 0x18 89#define TWSI_STATUS_DATA_WR_ACK 0x28 90#define TWSI_STATUS_ADDR_R_ACK 0x40 91#define TWSI_STATUS_DATA_RD_ACK 0x50 92#define TWSI_STATUS_DATA_RD_NOACK 0x58 93 94#define TWSI_BAUD_RATE 0x0c 95#define TWSI_BAUD_RATE_PARAM(M,N) ((((M) << 3) | ((N) & 0x7)) & 0x7f) 96#define TWSI_BAUD_RATE_RAW(C,M,N) ((C)/((10*(M+1))<<(N+1))) 97#define TWSI_BAUD_RATE_SLOW 50000 /* 50kHz */ 98#define TWSI_BAUD_RATE_FAST 100000 /* 100kHz */ 99 100#define TWSI_SOFT_RESET 0x1c 101 102#define TWSI_DEBUG 103#undef TWSI_DEBUG 104 105#ifdef TWSI_DEBUG 106#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0) 107#else 108#define debugf(fmt, args...) 109#endif 110 111struct mv_twsi_softc { 112 device_t dev; 113 struct resource *res[1]; /* SYS_RES_MEMORY */ 114 struct mtx mutex; 115 device_t iicbus; 116}; 117 118static struct mv_twsi_baud_rate { 119 uint32_t raw; 120 int param; 121 int m; 122 int n; 123} baud_rate[IIC_FASTEST + 1]; 124 125static int mv_twsi_probe(device_t); 126static int mv_twsi_attach(device_t); 127static int mv_twsi_detach(device_t); 128 129static int mv_twsi_reset(device_t dev, u_char speed, u_char addr, 130 u_char *oldaddr); 131static int mv_twsi_repeated_start(device_t dev, u_char slave, int timeout); 132static int mv_twsi_start(device_t dev, u_char slave, int timeout); 133static int mv_twsi_stop(device_t dev); 134static int mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, 135 int delay); 136static int mv_twsi_write(device_t dev, const char *buf, int len, int *sent, 137 int timeout); 138 139static struct resource_spec res_spec[] = { 140 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 141 { -1, 0 } 142}; 143 144static device_method_t mv_twsi_methods[] = { 145 /* device interface */ 146 DEVMETHOD(device_probe, mv_twsi_probe), 147 DEVMETHOD(device_attach, mv_twsi_attach), 148 DEVMETHOD(device_detach, mv_twsi_detach), 149 150 /* iicbus interface */ 151 DEVMETHOD(iicbus_callback, iicbus_null_callback), 152 DEVMETHOD(iicbus_repeated_start, mv_twsi_repeated_start), 153 DEVMETHOD(iicbus_start, mv_twsi_start), 154 DEVMETHOD(iicbus_stop, mv_twsi_stop), 155 DEVMETHOD(iicbus_write, mv_twsi_write), 156 DEVMETHOD(iicbus_read, mv_twsi_read), 157 DEVMETHOD(iicbus_reset, mv_twsi_reset), 158 DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 159 { 0, 0 } 160}; 161 162static devclass_t mv_twsi_devclass; 163 164static driver_t mv_twsi_driver = { 165 MV_TWSI_NAME, 166 mv_twsi_methods, 167 sizeof(struct mv_twsi_softc), 168}; 169 170DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0); 171DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0); 172MODULE_DEPEND(twsi, iicbus, 1, 1, 1); 173 174static __inline uint32_t 175TWSI_READ(struct mv_twsi_softc *sc, bus_size_t off) 176{ 177 178 return (bus_read_4(sc->res[0], off)); 179} 180 181static __inline void 182TWSI_WRITE(struct mv_twsi_softc *sc, bus_size_t off, uint32_t val) 183{ 184 185 bus_write_4(sc->res[0], off, val); 186} 187 188static __inline void 189twsi_control_clear(struct mv_twsi_softc *sc, uint32_t mask) 190{ 191 uint32_t val; 192 193 val = TWSI_READ(sc, TWSI_CONTROL); 194 val &= ~mask; 195 TWSI_WRITE(sc, TWSI_CONTROL, val); 196} 197 198static __inline void 199twsi_control_set(struct mv_twsi_softc *sc, uint32_t mask) 200{ 201 uint32_t val; 202 203 val = TWSI_READ(sc, TWSI_CONTROL); 204 val |= mask; 205 TWSI_WRITE(sc, TWSI_CONTROL, val); 206} 207 208static __inline void 209twsi_clear_iflg(struct mv_twsi_softc *sc) 210{ 211 212 DELAY(1000); 213 twsi_control_clear(sc, TWSI_CONTROL_IFLG); 214 DELAY(1000); 215} 216 217 218/* 219 * timeout given in us 220 * returns 221 * 0 on sucessfull mask change 222 * non-zero on timeout 223 */ 224static int 225twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask) 226{ 227 228 timeout /= 10; 229 while (!(TWSI_READ(sc, TWSI_CONTROL) & mask)) { 230 DELAY(10); 231 if (--timeout < 0) 232 return (timeout); 233 } 234 return (0); 235} 236 237 238/* 239 * 'timeout' is given in us. Note also that timeout handling is not exact -- 240 * twsi_locked_start() total wait can be more than 2 x timeout 241 * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START 242 * or TWSI_STATUS_RPTD_START 243 */ 244static int 245twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, 246 u_char slave, int timeout) 247{ 248 int read_access, iflg_set = 0; 249 uint32_t status; 250 251 mtx_assert(&sc->mutex, MA_OWNED); 252 253 if (mask == TWSI_STATUS_RPTD_START) 254 /* read IFLG to know if it should be cleared later; from NBSD */ 255 iflg_set = TWSI_READ(sc, TWSI_CONTROL) & TWSI_CONTROL_IFLG; 256 257 twsi_control_set(sc, TWSI_CONTROL_START); 258 259 if (mask == TWSI_STATUS_RPTD_START && iflg_set) { 260 debugf("IFLG set, clearing\n"); 261 twsi_clear_iflg(sc); 262 } 263 264 /* 265 * Without this delay we timeout checking IFLG if the timeout is 0. 266 * NBSD driver always waits here too. 267 */ 268 DELAY(1000); 269 270 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 271 debugf("timeout sending %sSTART condition\n", 272 mask == TWSI_STATUS_START ? "" : "repeated "); 273 return (IIC_ETIMEOUT); 274 } 275 276 status = TWSI_READ(sc, TWSI_STATUS); 277 if (status != mask) { 278 debugf("wrong status (%02x) after sending %sSTART condition\n", 279 status, mask == TWSI_STATUS_START ? "" : "repeated "); 280 return (IIC_ESTATUS); 281 } 282 283 TWSI_WRITE(sc, TWSI_DATA, slave); 284 DELAY(1000); 285 twsi_clear_iflg(sc); 286 287 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 288 debugf("timeout sending slave address\n"); 289 return (IIC_ETIMEOUT); 290 } 291 292 read_access = (slave & 0x1) ? 1 : 0; 293 status = TWSI_READ(sc, TWSI_STATUS); 294 if (status != (read_access ? 295 TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) { 296 debugf("no ACK (status: %02x) after sending slave address\n", 297 status); 298 return (IIC_ENOACK); 299 } 300 301 return (IIC_NOERR); 302} 303 304static int 305mv_twsi_probe(device_t dev) 306{ 307
|
| 308 if (!ofw_bus_status_okay(dev)) 309 return (ENXIO); 310
|
308 if (!ofw_bus_is_compatible(dev, "mrvl,twsi")) 309 return (ENXIO); 310 311 device_set_desc(dev, "Marvell Integrated I2C Bus Controller"); 312 return (BUS_PROBE_DEFAULT); 313} 314 315#define ABSSUB(a,b) (((a) > (b)) ? (a) - (b) : (b) - (a)) 316static void 317mv_twsi_cal_baud_rate(const uint32_t target, struct mv_twsi_baud_rate *rate) 318{ 319 uint32_t clk, cur, diff, diff0; 320 int m, n, m0, n0; 321 322 /* Calculate baud rate. */ 323 m0 = n0 = 4; /* Default values on reset */ 324 diff0 = 0xffffffff; 325 clk = get_tclk(); 326 327 for (n = 0; n < 8; n++) { 328 for (m = 0; m < 16; m++) { 329 cur = TWSI_BAUD_RATE_RAW(clk,m,n); 330 diff = ABSSUB(target, cur); 331 if (diff < diff0) { 332 m0 = m; 333 n0 = n; 334 diff0 = diff; 335 } 336 } 337 } 338 rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0); 339 rate->param = TWSI_BAUD_RATE_PARAM(m0, n0); 340 rate->m = m0; 341 rate->n = n0; 342} 343 344static int 345mv_twsi_attach(device_t dev) 346{ 347 struct mv_twsi_softc *sc; 348 phandle_t child, iicbusnode; 349 device_t childdev; 350 struct iicbus_ivar *devi; 351 char dname[32]; /* 32 is taken from struct u_device */ 352 uint32_t paddr; 353 int len, error; 354 355 sc = device_get_softc(dev); 356 sc->dev = dev; 357 bzero(baud_rate, sizeof(baud_rate)); 358 359 mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF); 360 361 /* Allocate IO resources */ 362 if (bus_alloc_resources(dev, res_spec, sc->res)) { 363 device_printf(dev, "could not allocate resources\n"); 364 mv_twsi_detach(dev); 365 return (ENXIO); 366 } 367 368 mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &baud_rate[IIC_SLOW]); 369 mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &baud_rate[IIC_FAST]); 370 if (bootverbose) 371 device_printf(dev, "calculated baud rates are:\n" 372 " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n" 373 " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n", 374 baud_rate[IIC_SLOW].raw / 1000, 375 baud_rate[IIC_SLOW].m, 376 baud_rate[IIC_SLOW].n, 377 baud_rate[IIC_FAST].raw / 1000, 378 baud_rate[IIC_FAST].m, 379 baud_rate[IIC_FAST].n); 380 381 sc->iicbus = device_add_child(dev, IICBUS_DEVNAME, -1); 382 if (sc->iicbus == NULL) { 383 device_printf(dev, "could not add iicbus child\n"); 384 mv_twsi_detach(dev); 385 return (ENXIO); 386 } 387 /* Attach iicbus. */ 388 bus_generic_attach(dev); 389 390 iicbusnode = 0; 391 /* Find iicbus as the child devices in the device tree. */ 392 for (child = OF_child(ofw_bus_get_node(dev)); child != 0; 393 child = OF_peer(child)) { 394 len = OF_getproplen(child, "model"); 395 if (len <= 0 || len > sizeof(dname) - 1) 396 continue; 397 error = OF_getprop(child, "model", &dname, len); 398 dname[len + 1] = '\0'; 399 if (error == -1) 400 continue; 401 len = strlen(dname); 402 if (len == strlen(IICBUS_DEVNAME) && 403 strncasecmp(dname, IICBUS_DEVNAME, len) == 0) { 404 iicbusnode = child; 405 break; 406 } 407 } 408 if (iicbusnode == 0) 409 goto attach_end; 410 411 /* Attach child devices onto iicbus. */ 412 for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) { 413 /* Get slave address. */ 414 error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)); 415 if (error == -1) 416 error = OF_getprop(child, "reg", &paddr, sizeof(paddr)); 417 if (error == -1) 418 continue; 419 420 /* Get device driver name. */ 421 len = OF_getproplen(child, "model"); 422 if (len <= 0 || len > sizeof(dname) - 1) 423 continue; 424 OF_getprop(child, "model", &dname, len); 425 dname[len + 1] = '\0'; 426 427 if (bootverbose) 428 device_printf(dev, "adding a device %s at %d.\n", 429 dname, fdt32_to_cpu(paddr)); 430 childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1); 431 devi = IICBUS_IVAR(childdev); 432 devi->addr = fdt32_to_cpu(paddr); 433 } 434 435attach_end: 436 bus_generic_attach(sc->iicbus); 437 438 return (0); 439} 440 441static int 442mv_twsi_detach(device_t dev) 443{ 444 struct mv_twsi_softc *sc; 445 int rv; 446 447 sc = device_get_softc(dev); 448 449 if ((rv = bus_generic_detach(dev)) != 0) 450 return (rv); 451 452 if (sc->iicbus != NULL) 453 if ((rv = device_delete_child(dev, sc->iicbus)) != 0) 454 return (rv); 455 456 bus_release_resources(dev, res_spec, sc->res); 457 458 mtx_destroy(&sc->mutex); 459 return (0); 460} 461 462/* 463 * Only slave mode supported, disregard [old]addr 464 */ 465static int 466mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 467{ 468 struct mv_twsi_softc *sc; 469 uint32_t param; 470 471 sc = device_get_softc(dev); 472 473 switch (speed) { 474 case IIC_SLOW: 475 case IIC_FAST: 476 param = baud_rate[speed].param; 477 break; 478 case IIC_FASTEST: 479 case IIC_UNKNOWN: 480 default: 481 param = baud_rate[IIC_FAST].param; 482 break; 483 } 484 485 mtx_lock(&sc->mutex); 486 TWSI_WRITE(sc, TWSI_SOFT_RESET, 0x0); 487 DELAY(2000); 488 TWSI_WRITE(sc, TWSI_BAUD_RATE, param); 489 TWSI_WRITE(sc, TWSI_CONTROL, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK); 490 DELAY(1000); 491 mtx_unlock(&sc->mutex); 492 493 return (0); 494} 495 496/* 497 * timeout is given in us 498 */ 499static int 500mv_twsi_repeated_start(device_t dev, u_char slave, int timeout) 501{ 502 struct mv_twsi_softc *sc; 503 int rv; 504 505 sc = device_get_softc(dev); 506 507 mtx_lock(&sc->mutex); 508 rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave, 509 timeout); 510 mtx_unlock(&sc->mutex); 511 512 if (rv) { 513 mv_twsi_stop(dev); 514 return (rv); 515 } else 516 return (IIC_NOERR); 517} 518 519/* 520 * timeout is given in us 521 */ 522static int 523mv_twsi_start(device_t dev, u_char slave, int timeout) 524{ 525 struct mv_twsi_softc *sc; 526 int rv; 527 528 sc = device_get_softc(dev); 529 530 mtx_lock(&sc->mutex); 531 rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout); 532 mtx_unlock(&sc->mutex); 533 534 if (rv) { 535 mv_twsi_stop(dev); 536 return (rv); 537 } else 538 return (IIC_NOERR); 539} 540 541static int 542mv_twsi_stop(device_t dev) 543{ 544 struct mv_twsi_softc *sc; 545 546 sc = device_get_softc(dev); 547 548 mtx_lock(&sc->mutex); 549 twsi_control_set(sc, TWSI_CONTROL_STOP); 550 DELAY(1000); 551 twsi_clear_iflg(sc); 552 mtx_unlock(&sc->mutex); 553 554 return (IIC_NOERR); 555} 556 557static int 558mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) 559{ 560 struct mv_twsi_softc *sc; 561 uint32_t status; 562 int last_byte, rv; 563 564 sc = device_get_softc(dev); 565 566 mtx_lock(&sc->mutex); 567 *read = 0; 568 while (*read < len) { 569 /* 570 * Check if we are reading last byte of the last buffer, 571 * do not send ACK then, per I2C specs 572 */ 573 last_byte = ((*read == len - 1) && last) ? 1 : 0; 574 if (last_byte) 575 twsi_control_clear(sc, TWSI_CONTROL_ACK); 576 else 577 twsi_control_set(sc, TWSI_CONTROL_ACK); 578 579 DELAY (1000); 580 twsi_clear_iflg(sc); 581 582 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) { 583 debugf("timeout reading data\n"); 584 rv = IIC_ETIMEOUT; 585 goto out; 586 } 587 588 status = TWSI_READ(sc, TWSI_STATUS); 589 if (status != (last_byte ? 590 TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) { 591 debugf("wrong status (%02x) while reading\n", status); 592 rv = IIC_ESTATUS; 593 goto out; 594 } 595 596 *buf++ = TWSI_READ(sc, TWSI_DATA); 597 (*read)++; 598 } 599 rv = IIC_NOERR; 600out: 601 mtx_unlock(&sc->mutex); 602 return (rv); 603} 604 605static int 606mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) 607{ 608 struct mv_twsi_softc *sc; 609 uint32_t status; 610 int rv; 611 612 sc = device_get_softc(dev); 613 614 mtx_lock(&sc->mutex); 615 *sent = 0; 616 while (*sent < len) { 617 TWSI_WRITE(sc, TWSI_DATA, *buf++); 618 619 twsi_clear_iflg(sc); 620 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 621 debugf("timeout writing data\n"); 622 rv = IIC_ETIMEOUT; 623 goto out; 624 } 625 626 status = TWSI_READ(sc, TWSI_STATUS); 627 if (status != TWSI_STATUS_DATA_WR_ACK) { 628 debugf("wrong status (%02x) while writing\n", status); 629 rv = IIC_ESTATUS; 630 goto out; 631 } 632 (*sent)++; 633 } 634 rv = IIC_NOERR; 635out: 636 mtx_unlock(&sc->mutex); 637 return (rv); 638}
| 311 if (!ofw_bus_is_compatible(dev, "mrvl,twsi")) 312 return (ENXIO); 313 314 device_set_desc(dev, "Marvell Integrated I2C Bus Controller"); 315 return (BUS_PROBE_DEFAULT); 316} 317 318#define ABSSUB(a,b) (((a) > (b)) ? (a) - (b) : (b) - (a)) 319static void 320mv_twsi_cal_baud_rate(const uint32_t target, struct mv_twsi_baud_rate *rate) 321{ 322 uint32_t clk, cur, diff, diff0; 323 int m, n, m0, n0; 324 325 /* Calculate baud rate. */ 326 m0 = n0 = 4; /* Default values on reset */ 327 diff0 = 0xffffffff; 328 clk = get_tclk(); 329 330 for (n = 0; n < 8; n++) { 331 for (m = 0; m < 16; m++) { 332 cur = TWSI_BAUD_RATE_RAW(clk,m,n); 333 diff = ABSSUB(target, cur); 334 if (diff < diff0) { 335 m0 = m; 336 n0 = n; 337 diff0 = diff; 338 } 339 } 340 } 341 rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0); 342 rate->param = TWSI_BAUD_RATE_PARAM(m0, n0); 343 rate->m = m0; 344 rate->n = n0; 345} 346 347static int 348mv_twsi_attach(device_t dev) 349{ 350 struct mv_twsi_softc *sc; 351 phandle_t child, iicbusnode; 352 device_t childdev; 353 struct iicbus_ivar *devi; 354 char dname[32]; /* 32 is taken from struct u_device */ 355 uint32_t paddr; 356 int len, error; 357 358 sc = device_get_softc(dev); 359 sc->dev = dev; 360 bzero(baud_rate, sizeof(baud_rate)); 361 362 mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF); 363 364 /* Allocate IO resources */ 365 if (bus_alloc_resources(dev, res_spec, sc->res)) { 366 device_printf(dev, "could not allocate resources\n"); 367 mv_twsi_detach(dev); 368 return (ENXIO); 369 } 370 371 mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &baud_rate[IIC_SLOW]); 372 mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &baud_rate[IIC_FAST]); 373 if (bootverbose) 374 device_printf(dev, "calculated baud rates are:\n" 375 " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n" 376 " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n", 377 baud_rate[IIC_SLOW].raw / 1000, 378 baud_rate[IIC_SLOW].m, 379 baud_rate[IIC_SLOW].n, 380 baud_rate[IIC_FAST].raw / 1000, 381 baud_rate[IIC_FAST].m, 382 baud_rate[IIC_FAST].n); 383 384 sc->iicbus = device_add_child(dev, IICBUS_DEVNAME, -1); 385 if (sc->iicbus == NULL) { 386 device_printf(dev, "could not add iicbus child\n"); 387 mv_twsi_detach(dev); 388 return (ENXIO); 389 } 390 /* Attach iicbus. */ 391 bus_generic_attach(dev); 392 393 iicbusnode = 0; 394 /* Find iicbus as the child devices in the device tree. */ 395 for (child = OF_child(ofw_bus_get_node(dev)); child != 0; 396 child = OF_peer(child)) { 397 len = OF_getproplen(child, "model"); 398 if (len <= 0 || len > sizeof(dname) - 1) 399 continue; 400 error = OF_getprop(child, "model", &dname, len); 401 dname[len + 1] = '\0'; 402 if (error == -1) 403 continue; 404 len = strlen(dname); 405 if (len == strlen(IICBUS_DEVNAME) && 406 strncasecmp(dname, IICBUS_DEVNAME, len) == 0) { 407 iicbusnode = child; 408 break; 409 } 410 } 411 if (iicbusnode == 0) 412 goto attach_end; 413 414 /* Attach child devices onto iicbus. */ 415 for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) { 416 /* Get slave address. */ 417 error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)); 418 if (error == -1) 419 error = OF_getprop(child, "reg", &paddr, sizeof(paddr)); 420 if (error == -1) 421 continue; 422 423 /* Get device driver name. */ 424 len = OF_getproplen(child, "model"); 425 if (len <= 0 || len > sizeof(dname) - 1) 426 continue; 427 OF_getprop(child, "model", &dname, len); 428 dname[len + 1] = '\0'; 429 430 if (bootverbose) 431 device_printf(dev, "adding a device %s at %d.\n", 432 dname, fdt32_to_cpu(paddr)); 433 childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1); 434 devi = IICBUS_IVAR(childdev); 435 devi->addr = fdt32_to_cpu(paddr); 436 } 437 438attach_end: 439 bus_generic_attach(sc->iicbus); 440 441 return (0); 442} 443 444static int 445mv_twsi_detach(device_t dev) 446{ 447 struct mv_twsi_softc *sc; 448 int rv; 449 450 sc = device_get_softc(dev); 451 452 if ((rv = bus_generic_detach(dev)) != 0) 453 return (rv); 454 455 if (sc->iicbus != NULL) 456 if ((rv = device_delete_child(dev, sc->iicbus)) != 0) 457 return (rv); 458 459 bus_release_resources(dev, res_spec, sc->res); 460 461 mtx_destroy(&sc->mutex); 462 return (0); 463} 464 465/* 466 * Only slave mode supported, disregard [old]addr 467 */ 468static int 469mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 470{ 471 struct mv_twsi_softc *sc; 472 uint32_t param; 473 474 sc = device_get_softc(dev); 475 476 switch (speed) { 477 case IIC_SLOW: 478 case IIC_FAST: 479 param = baud_rate[speed].param; 480 break; 481 case IIC_FASTEST: 482 case IIC_UNKNOWN: 483 default: 484 param = baud_rate[IIC_FAST].param; 485 break; 486 } 487 488 mtx_lock(&sc->mutex); 489 TWSI_WRITE(sc, TWSI_SOFT_RESET, 0x0); 490 DELAY(2000); 491 TWSI_WRITE(sc, TWSI_BAUD_RATE, param); 492 TWSI_WRITE(sc, TWSI_CONTROL, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK); 493 DELAY(1000); 494 mtx_unlock(&sc->mutex); 495 496 return (0); 497} 498 499/* 500 * timeout is given in us 501 */ 502static int 503mv_twsi_repeated_start(device_t dev, u_char slave, int timeout) 504{ 505 struct mv_twsi_softc *sc; 506 int rv; 507 508 sc = device_get_softc(dev); 509 510 mtx_lock(&sc->mutex); 511 rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave, 512 timeout); 513 mtx_unlock(&sc->mutex); 514 515 if (rv) { 516 mv_twsi_stop(dev); 517 return (rv); 518 } else 519 return (IIC_NOERR); 520} 521 522/* 523 * timeout is given in us 524 */ 525static int 526mv_twsi_start(device_t dev, u_char slave, int timeout) 527{ 528 struct mv_twsi_softc *sc; 529 int rv; 530 531 sc = device_get_softc(dev); 532 533 mtx_lock(&sc->mutex); 534 rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout); 535 mtx_unlock(&sc->mutex); 536 537 if (rv) { 538 mv_twsi_stop(dev); 539 return (rv); 540 } else 541 return (IIC_NOERR); 542} 543 544static int 545mv_twsi_stop(device_t dev) 546{ 547 struct mv_twsi_softc *sc; 548 549 sc = device_get_softc(dev); 550 551 mtx_lock(&sc->mutex); 552 twsi_control_set(sc, TWSI_CONTROL_STOP); 553 DELAY(1000); 554 twsi_clear_iflg(sc); 555 mtx_unlock(&sc->mutex); 556 557 return (IIC_NOERR); 558} 559 560static int 561mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) 562{ 563 struct mv_twsi_softc *sc; 564 uint32_t status; 565 int last_byte, rv; 566 567 sc = device_get_softc(dev); 568 569 mtx_lock(&sc->mutex); 570 *read = 0; 571 while (*read < len) { 572 /* 573 * Check if we are reading last byte of the last buffer, 574 * do not send ACK then, per I2C specs 575 */ 576 last_byte = ((*read == len - 1) && last) ? 1 : 0; 577 if (last_byte) 578 twsi_control_clear(sc, TWSI_CONTROL_ACK); 579 else 580 twsi_control_set(sc, TWSI_CONTROL_ACK); 581 582 DELAY (1000); 583 twsi_clear_iflg(sc); 584 585 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) { 586 debugf("timeout reading data\n"); 587 rv = IIC_ETIMEOUT; 588 goto out; 589 } 590 591 status = TWSI_READ(sc, TWSI_STATUS); 592 if (status != (last_byte ? 593 TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) { 594 debugf("wrong status (%02x) while reading\n", status); 595 rv = IIC_ESTATUS; 596 goto out; 597 } 598 599 *buf++ = TWSI_READ(sc, TWSI_DATA); 600 (*read)++; 601 } 602 rv = IIC_NOERR; 603out: 604 mtx_unlock(&sc->mutex); 605 return (rv); 606} 607 608static int 609mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) 610{ 611 struct mv_twsi_softc *sc; 612 uint32_t status; 613 int rv; 614 615 sc = device_get_softc(dev); 616 617 mtx_lock(&sc->mutex); 618 *sent = 0; 619 while (*sent < len) { 620 TWSI_WRITE(sc, TWSI_DATA, *buf++); 621 622 twsi_clear_iflg(sc); 623 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 624 debugf("timeout writing data\n"); 625 rv = IIC_ETIMEOUT; 626 goto out; 627 } 628 629 status = TWSI_READ(sc, TWSI_STATUS); 630 if (status != TWSI_STATUS_DATA_WR_ACK) { 631 debugf("wrong status (%02x) while writing\n", status); 632 rv = IIC_ESTATUS; 633 goto out; 634 } 635 (*sent)++; 636 } 637 rv = IIC_NOERR; 638out: 639 mtx_unlock(&sc->mutex); 640 return (rv); 641}
|