i2c - gpio(二)

2014-11-24 09:08:26 · 作者: · 浏览: 1
i2c_gpio *i2c)
{
int i;
uint8_t ack;

spin_lock_irq(&i2c->lock);
i2c_start();

ack = i2c_send_byte((i2c->msg->addr << 1) | 0x00);
if(ack){
goto out;
}

for(i = 0; i < i2c->msg->len; i++) {
ack = i2c_send_byte(i2c->msg->buf[i]);
if(ack){
goto out;
}
}

out:
i2c_stop();
spin_unlock_irq(&i2c->lock);
return ack;
}

static int recv_i2c(struct atxx_i2c_gpio *i2c)
{
int i;
uint8_t ack;

spin_lock_irq(&i2c->lock);
i2c_start();

ack = i2c_send_byte((i2c->msg->addr << 1) | 0x01);
if(ack){
goto out;
}

for(i = 0; i < i2c->msg->len - 1; i++) {
i2c_read_byte(&i2c->msg->buf[i], 0);
}

i2c_read_byte(&i2c->msg->buf[i2c->msg->len - 1], 1);
out:
i2c_stop();
spin_unlock_irq(&i2c->lock);
return ack;
}

static int i2c_atxx_gpio_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
int i, ret;
struct atxx_i2c_gpio *i2c = i2c_get_adapdata(adap);

for (i = 0; i < num; i++) {
i2c->msg = &msgs[i];
i2c->msg->flags = msgs[i].flags;

if (i2c->msg->flags & I2C_M_RD) {
ret = recv_i2c(i2c);
if (ret) {
printk("recv_i2c failed. dev_name(%s).addr = 0x%02x\n",
dev_name(i2c->dev), i2c->msg[0].addr);
return -EAGAIN;
}
} else {
ret = send_i2c(i2c);
if (ret) {
printk("send_i2c failed. dev_name(%s).addr = 0x%02x\n",
dev_name(i2c->dev), i2c->msg[0].addr);
return -EAGAIN;
}
}
}

return num;
}

static uint32_t i2c_atxx_gpio_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

static struct i2c_algorithm i2c_atxx_gpio_algo = {
.master_xfer = i2c_atxx_gpio_xfer,
.functionality = i2c_atxx_gpio_func,
};

static int i2c_atxx_gpio_probe(struct platform_device *pdev)
{
int ret;
struct atxx_i2c_gpio *i2c;

ret = i2c_gpio_init();
if(ret) {
dev_err(&pdev->dev, "couldn't request gpio\n");
return ret;
}

i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
if (!i2c) {
dev_err(&pdev->dev, "couldn't allocate memory\n");;
ret = -ENOMEM;
goto err_mem;
}

spin_lock_init(&i2c->lock);

i2c->dev = &pdev->dev;
i2c->adap.owner = THIS_MODULE;
i2c->adap.algo = &i2c_atxx_gpio_algo;
i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
i2c->adap.timeout = I2C_ATXX_TIMEOUT;
i2c->adap.retries = I2C_ATXX_RETRIES;
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &pdev->dev;
i2c->adap.nr = pdev->id != -1 pdev->id : 0;

sprintf(i2c->adap.name, "ATXX i2c gpio adapter");
platform_set_drvdata(pdev, i2c);
i2c_set_adapdata(&i2c->adap, i2c);

ret = i2c_add_numbered_adapter(&i2c->adap);
if (ret) {
dev_err(i2c->dev, "failure adding adapter\n");
goto err_adp;
}

return 0;

err_adp:
kfree(i2c);
err_mem:
i2c_gpio_free();
return ret;
}

static int i2c_atxx_gpio_remove(struct platform_device *pdev)
{
struct atxx_i2c_g