// SPDX-License-Identifier: GPL-2.0-only /* ------------------------------------------------------------------------- */ /* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x */ /* ------------------------------------------------------------------------- */ /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd * <Peter dot Milne at D hyphen TACQ dot com> * * With acknowledgements to i2c-algo-ibm_ocp.c by * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com * * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund: * * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund * * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> * * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005: * * - Use driver model to pass per-chip info instead of hardcoding and #ifdefs * - Use ioremap/__raw_readl/__raw_writel instead of direct dereference * - Make it work with IXP46x chips * - Cleanup function names, coding style, etc * * - writing to local target address causes latchup on iop331. * fix: driver refuses to address self.
*/
/* * Every time unit enable is asserted, GPOD needs to be cleared * on IOP3XX to avoid data corruption on the bus. We use the * gpiod_set_raw_value() to make sure the 0 hits the hardware * GPOD register. These descriptors are only passed along to * the device if this is necessary.
*/ if (iop3xx_adap->gpio_scl)
gpiod_set_raw_value(iop3xx_adap->gpio_scl, 0); if (iop3xx_adap->gpio_sda)
gpiod_set_raw_value(iop3xx_adap->gpio_sda, 0);
/* NB SR bits not same position as CR IE bits :-( */
iop3xx_adap->SR_enabled =
IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
/* * NB: the handler has to clear the source of the interrupt! * Then it passes the SR flags of interest to BH via adap data
*/ static irqreturn_t
iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
{ struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
spin_lock_irqsave(&iop3xx_adap->lock, flags);
sr = iop3xx_adap->SR_received;
iop3xx_adap->SR_received = 0;
spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
return sr;
}
/* * sleep until interrupted, then recover and analyse the SR * saved by handler
*/ typedefint (*compare_func)(unsigned test, unsigned mask); /* returns 1 on correct comparison */
staticint
iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, unsigned flags, unsigned *status,
compare_func compare)
{ unsigned sr = 0; int interrupted; int done; int rc = 0;
staticint
iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, constchar *buf, int count)
{ struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; int ii; int rc = 0;
for (ii = 0; rc == 0 && ii != count; ++ii)
rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii == count-1); return rc;
}
staticint
iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
{ struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; int ii; int rc = 0;
for (ii = 0; rc == 0 && ii != count; ++ii)
rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii == count-1);
return rc;
}
/* * Description: This function implements combined transactions. Combined * transactions consist of combinations of reading and writing blocks of data. * FROM THE SAME ADDRESS * Each transfer (i.e. a read or a write) is separated by a repeated start * condition.
*/ staticint
iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg *pmsg)
{ struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; int rc;
staticint
iop3xx_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
{ struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; int im = 0; int ret = 0; int status;
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.