Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3030 → Rev 3031

/drivers/video/drm/i2c/i2c-algo-bit.c
15,7 → 15,8
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.
* ------------------------------------------------------------------------- */
 
/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
24,11 → 25,13
#include <types.h>
#include <list.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <syscall.h>
#include <errno.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
 
#define I2C_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */
 
/* ----- global defines ----------------------------------------------- */
 
40,13 → 43,19
} while (0)
#else
#define bit_dbg(level, dev, format, args...) \
do {} while (0)
do { /* dbgprintf(format, ##args); */ } while (0)
#endif /* DEBUG */
 
/* ----- global variables --------------------------------------------- */
 
static int bit_test; /* see if the line-setting functions work */
static int bit_test = 0; /* see if the line-setting functions work */
 
#ifdef DEBUG
static int i2c_debug = 1;
module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(i2c_debug,
"debug level - 0 off; 1 normal; 2 verbose; 3 very verbose");
#endif
 
/* --- setting states on the bus with the right timing: --------------- */
 
87,7 → 96,7
if (!adap->getscl)
goto done;
 
// start = jiffies;
start = GetTimerTicks();
while (!getscl(adap)) {
/* This hw knows how to read the clock line, so we wait
* until it actually gets high. This is safer as some
94,19 → 103,16
* chips may hold it low ("clock stretching") while they
* are processing data internally.
*/
// if (time_after(jiffies, start + adap->timeout))
// return -ETIMEDOUT;
 
udelay(adap->udelay);
 
// cond_resched();
if (time_after(GetTimerTicks(), start + adap->timeout)) {
/* Test one last time, as we may have been preempted
* between last check and timeout test.
*/
if (getscl(adap))
break;
return -ETIMEDOUT;
}
#ifdef DEBUG
if (jiffies != start && i2c_debug >= 3)
pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go "
"high\n", jiffies - start);
#endif
 
udelay(1);
}
done:
udelay(adap->udelay);
return 0;
239,12 → 245,14
}
 
if (adap->getscl == NULL)
pr_info("%s: Testing SDA only, SCL is not readable\n", name);
dbgprintf("%s: Testing SDA only, SCL is not readable\n", name);
 
sda = getsda(adap);
scl = (adap->getscl == NULL) ? 1 : getscl(adap);
if (!scl || !sda) {
printk(KERN_WARNING "%s: bus seems to be busy\n", name);
printk(KERN_WARNING
"%s: bus seems to be busy (scl=%d, sda=%d)\n",
name, scl, sda);
goto bailout;
}
 
303,7 → 311,7
if (adap->post_xfer)
adap->post_xfer(i2c_adap);
 
pr_info("%s: Test OK\n", name);
dbgprintf("%s: Test OK\n", name);
return 0;
bailout:
sdahi(adap);
372,7 → 380,7
* the SMBus PEC was wrong.
*/
} else if (retval == 0) {
// dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n");
dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n");
return -EIO;
 
/* Timeout; or (someday) lost arbitration
383,8 → 391,8
* to know or care about this ... it is *NOT* an error.
*/
} else {
// dev_err(&i2c_adap->dev, "sendbytes: error %d\n",
// retval);
dev_err(&i2c_adap->dev, "sendbytes: error %d\n",
retval);
return retval;
}
}
400,8 → 408,8
setsda(adap, 0);
udelay((adap->udelay + 1) / 2);
if (sclhi(adap) < 0) { /* timeout */
// dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n");
// return -ETIMEDOUT;
dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n");
return -ETIMEDOUT;
}
scllo(adap);
return 0;
433,9 → 441,9
if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
if (!(flags & I2C_M_NO_RD_ACK))
acknak(i2c_adap, 0);
// dev_err(&i2c_adap->dev, "readbytes: invalid "
// "block length (%d)\n", inval);
return -EREMOTEIO;
dev_err(&i2c_adap->dev, "readbytes: invalid "
"block length (%d)\n", inval);
return -EPROTO;
}
/* The original count value accounts for the extra
bytes, that is, either 1 for a regular transaction,
464,7 → 472,7
* reads, writes as well as 10bit-addresses.
* returns:
* 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
* -x an error occurred (like: -EREMOTEIO if the device did not answer, or
* -x an error occurred (like: -ENXIO if the device did not answer, or
* -ETIMEDOUT, for example if the lines are stuck...)
*/
static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
480,21 → 488,21
 
if (flags & I2C_M_TEN) {
/* a ten bit address */
addr = 0xf0 | ((msg->addr >> 7) & 0x03);
addr = 0xf0 | ((msg->addr >> 7) & 0x06);
bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
/* try extended address code...*/
ret = try_address(i2c_adap, addr, retries);
if ((ret != 1) && !nak_ok) {
// dev_err(&i2c_adap->dev,
// "died at extended address code\n");
return -EREMOTEIO;
dev_err(&i2c_adap->dev,
"died at extended address code\n");
return -ENXIO;
}
/* the remaining 8 bit address */
ret = i2c_outb(i2c_adap, msg->addr & 0x7f);
ret = i2c_outb(i2c_adap, msg->addr & 0xff);
if ((ret != 1) && !nak_ok) {
/* the chip did not ack / xmission error occurred */
// dev_err(&i2c_adap->dev, "died at 2nd address code\n");
return -EREMOTEIO;
dev_err(&i2c_adap->dev, "died at 2nd address code\n");
return -ENXIO;
}
if (flags & I2C_M_RD) {
bit_dbg(3, &i2c_adap->dev, "emitting repeated "
504,9 → 512,9
addr |= 0x01;
ret = try_address(i2c_adap, addr, retries);
if ((ret != 1) && !nak_ok) {
// dev_err(&i2c_adap->dev,
// "died at repeated address code\n");
return -EREMOTEIO;
dev_err(&i2c_adap->dev,
"died at repeated address code\n");
return -EIO;
}
}
} else { /* normal 7bit address */
531,7 → 539,6
int i, ret;
unsigned short nak_ok;
 
//ENTER();
if (adap->pre_xfer) {
ret = adap->pre_xfer(i2c_adap);
if (ret < 0)
565,7 → 572,7
ret, ret == 1 ? "" : "s");
if (ret < pmsg->len) {
if (ret >= 0)
ret = -EREMOTEIO;
ret = -EIO;
goto bailout;
}
} else {
576,7 → 583,7
ret, ret == 1 ? "" : "s");
if (ret < pmsg->len) {
if (ret >= 0)
ret = -EREMOTEIO;
ret = -EIO;
goto bailout;
}
}
586,7 → 593,6
bailout:
bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
i2c_stop(adap);
// LEAVE();
 
if (adap->post_xfer)
adap->post_xfer(i2c_adap);
595,7 → 601,7
 
static u32 bit_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_SMBUS_READ_BLOCK_DATA |
I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
604,10 → 610,11
 
/* -----exported algorithm data: ------------------------------------- */
 
static const struct i2c_algorithm i2c_bit_algo = {
const struct i2c_algorithm i2c_bit_algo = {
.master_xfer = bit_xfer,
.functionality = bit_func,
};
EXPORT_SYMBOL(i2c_bit_algo);
 
/*
* registering functions to load algorithms at runtime
620,7 → 627,7
 
if (bit_test) {
ret = test_bus(adap);
if (ret < 0)
if (bit_test >= 2 && ret < 0)
return -ENODEV;
}
 
628,6 → 635,11
adap->algo = &i2c_bit_algo;
adap->retries = 3;
 
/* Complain if SCL can't be read */
if (bit_adap->getscl == NULL) {
dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n");
dev_warn(&adap->dev, "Bus may be unreliable\n");
}
return 0;
}
 
/drivers/video/drm/i2c/i2c-core.c
14,15 → 14,20
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA. */
/* ------------------------------------------------------------------------- */
 
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
Jean Delvare <khali@linux-fr.org> */
Jean Delvare <khali@linux-fr.org>
Mux support by Rodolfo Giometti <giometti@enneenne.com> and
Michael Lawnick <michael.lawnick.ext@nsn.com> */
 
#include <types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <list.h>
#include <errno.h>
#include <linux/i2c.h>
29,7 → 34,254
#include <syscall.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#if 0
 
static ssize_t
show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
}
 
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
static struct attribute *i2c_dev_attrs[] = {
&dev_attr_name.attr,
/* modalias helps coldplug: modprobe $(cat .../modalias) */
&dev_attr_modalias.attr,
NULL
};
 
static struct attribute_group i2c_dev_attr_group = {
.attrs = i2c_dev_attrs,
};
 
static const struct attribute_group *i2c_dev_attr_groups[] = {
&i2c_dev_attr_group,
NULL
};
 
static const struct dev_pm_ops i2c_device_pm_ops = {
.suspend = i2c_device_pm_suspend,
.resume = i2c_device_pm_resume,
.freeze = i2c_device_pm_freeze,
.thaw = i2c_device_pm_thaw,
.poweroff = i2c_device_pm_poweroff,
.restore = i2c_device_pm_restore,
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
pm_generic_runtime_idle
)
};
 
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = &i2c_device_pm_ops,
};
EXPORT_SYMBOL_GPL(i2c_bus_type);
 
static struct device_type i2c_client_type = {
.groups = i2c_dev_attr_groups,
.uevent = i2c_device_uevent,
.release = i2c_client_dev_release,
};
 
 
/**
* i2c_verify_client - return parameter as i2c_client, or NULL
* @dev: device, probably from some driver model iterator
*
* When traversing the driver model tree, perhaps using driver model
* iterators like @device_for_each_child(), you can't assume very much
* about the nodes you find. Use this function to avoid oopses caused
* by wrongly treating some non-I2C device as an i2c_client.
*/
struct i2c_client *i2c_verify_client(struct device *dev)
{
return (dev->type == &i2c_client_type)
? to_i2c_client(dev)
: NULL;
}
EXPORT_SYMBOL(i2c_verify_client);
 
 
/* This is a permissive address validity check, I2C address map constraints
* are purposely not enforced, except for the general call address. */
static int i2c_check_client_addr_validity(const struct i2c_client *client)
{
if (client->flags & I2C_CLIENT_TEN) {
/* 10-bit address, all values are valid */
if (client->addr > 0x3ff)
return -EINVAL;
} else {
/* 7-bit address, reject the general call address */
if (client->addr == 0x00 || client->addr > 0x7f)
return -EINVAL;
}
return 0;
}
 
/* And this is a strict address validity check, used when probing. If a
* device uses a reserved address, then it shouldn't be probed. 7-bit
* addressing is assumed, 10-bit address devices are rare and should be
* explicitly enumerated. */
static int i2c_check_addr_validity(unsigned short addr)
{
/*
* Reserved addresses per I2C specification:
* 0x00 General call address / START byte
* 0x01 CBUS address
* 0x02 Reserved for different bus format
* 0x03 Reserved for future purposes
* 0x04-0x07 Hs-mode master code
* 0x78-0x7b 10-bit slave addressing
* 0x7c-0x7f Reserved for future purposes
*/
if (addr < 0x08 || addr > 0x77)
return -EINVAL;
return 0;
}
 
static int __i2c_check_addr_busy(struct device *dev, void *addrp)
{
struct i2c_client *client = i2c_verify_client(dev);
int addr = *(int *)addrp;
 
if (client && client->addr == addr)
return -EBUSY;
return 0;
}
 
/* walk up mux tree */
static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr)
{
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result;
 
result = device_for_each_child(&adapter->dev, &addr,
__i2c_check_addr_busy);
 
if (!result && parent)
result = i2c_check_mux_parents(parent, addr);
 
return result;
}
 
/* recurse down mux tree */
static int i2c_check_mux_children(struct device *dev, void *addrp)
{
int result;
 
if (dev->type == &i2c_adapter_type)
result = device_for_each_child(dev, addrp,
i2c_check_mux_children);
else
result = __i2c_check_addr_busy(dev, addrp);
 
return result;
}
 
static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
{
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result = 0;
 
if (parent)
result = i2c_check_mux_parents(parent, addr);
 
if (!result)
result = device_for_each_child(&adapter->dev, &addr,
i2c_check_mux_children);
 
return result;
}
 
/**
* i2c_lock_adapter - Get exclusive access to an I2C bus segment
* @adapter: Target I2C bus segment
*/
void i2c_lock_adapter(struct i2c_adapter *adapter)
{
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
 
if (parent)
i2c_lock_adapter(parent);
else
rt_mutex_lock(&adapter->bus_lock);
}
EXPORT_SYMBOL_GPL(i2c_lock_adapter);
 
/**
* i2c_trylock_adapter - Try to get exclusive access to an I2C bus segment
* @adapter: Target I2C bus segment
*/
static int i2c_trylock_adapter(struct i2c_adapter *adapter)
{
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
 
if (parent)
return i2c_trylock_adapter(parent);
else
return rt_mutex_trylock(&adapter->bus_lock);
}
 
/**
* i2c_unlock_adapter - Release exclusive access to an I2C bus segment
* @adapter: Target I2C bus segment
*/
void i2c_unlock_adapter(struct i2c_adapter *adapter)
{
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
 
if (parent)
i2c_unlock_adapter(parent);
else
rt_mutex_unlock(&adapter->bus_lock);
}
EXPORT_SYMBOL_GPL(i2c_unlock_adapter);
 
#endif
 
 
/**
* i2c_transfer - execute a single or combined I2C message
* @adap: Handle to I2C bus
* @msgs: One or more messages to execute before STOP is issued to
65,22 → 317,24
 
if (adap->algo->master_xfer) {
 
/* Retry automatically on arbitration loss */
orig_jiffies = GetTimerTicks();
 
/* Retry automatically on arbitration loss */
orig_jiffies = 0;
for (ret = 0, try = 0; try <= adap->retries; try++) {
 
ret = adap->algo->master_xfer(adap, msgs, num);
if (ret != -EAGAIN)
break;
// if (time_after(jiffies, orig_jiffies + adap->timeout))
// break;
 
if (time_after(GetTimerTicks(), orig_jiffies + adap->timeout))
break;
 
delay(1);
}
// mutex_unlock(&adap->bus_lock);
return ret;
} else {
// dev_dbg(&adap->dev, "I2C level transfers not supported\n");
dbgprintf("I2C level transfers not supported\n");
return -EOPNOTSUPP;
}
}