linux/drivers/mfd/tps65912-i2c.c
<<
>>
Prefs
   1/*
   2 * tps65912-i2c.c  --  I2C access for TI TPS65912x PMIC
   3 *
   4 * Copyright 2011 Texas Instruments Inc.
   5 *
   6 * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
   7 *
   8 *  This program is free software; you can redistribute it and/or modify it
   9 *  under  the terms of the GNU General  Public License as published by the
  10 *  Free Software Foundation;  either version 2 of the License, or (at your
  11 *  option) any later version.
  12 *
  13 *  This driver is based on wm8350 implementation.
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/moduleparam.h>
  18#include <linux/init.h>
  19#include <linux/slab.h>
  20#include <linux/gpio.h>
  21#include <linux/i2c.h>
  22#include <linux/mfd/core.h>
  23#include <linux/mfd/tps65912.h>
  24
  25static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg,
  26                                  int bytes, void *dest)
  27{
  28        struct i2c_client *i2c = tps65912->control_data;
  29        struct i2c_msg xfer[2];
  30        int ret;
  31
  32        /* Write register */
  33        xfer[0].addr = i2c->addr;
  34        xfer[0].flags = 0;
  35        xfer[0].len = 1;
  36        xfer[0].buf = &reg;
  37
  38        /* Read data */
  39        xfer[1].addr = i2c->addr;
  40        xfer[1].flags = I2C_M_RD;
  41        xfer[1].len = bytes;
  42        xfer[1].buf = dest;
  43
  44        ret = i2c_transfer(i2c->adapter, xfer, 2);
  45        if (ret == 2)
  46                ret = 0;
  47        else if (ret >= 0)
  48                ret = -EIO;
  49        return ret;
  50}
  51
  52static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg,
  53                                   int bytes, void *src)
  54{
  55        struct i2c_client *i2c = tps65912->control_data;
  56        /* we add 1 byte for device register */
  57        u8 msg[TPS6591X_MAX_REGISTER + 1];
  58        int ret;
  59
  60        if (bytes > TPS6591X_MAX_REGISTER)
  61                return -EINVAL;
  62
  63        msg[0] = reg;
  64        memcpy(&msg[1], src, bytes);
  65
  66        ret = i2c_master_send(i2c, msg, bytes + 1);
  67        if (ret < 0)
  68                return ret;
  69        if (ret != bytes + 1)
  70                return -EIO;
  71
  72        return 0;
  73}
  74
  75static int tps65912_i2c_probe(struct i2c_client *i2c,
  76                            const struct i2c_device_id *id)
  77{
  78        struct tps65912 *tps65912;
  79
  80        tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL);
  81        if (tps65912 == NULL)
  82                return -ENOMEM;
  83
  84        i2c_set_clientdata(i2c, tps65912);
  85        tps65912->dev = &i2c->dev;
  86        tps65912->control_data = i2c;
  87        tps65912->read = tps65912_i2c_read;
  88        tps65912->write = tps65912_i2c_write;
  89
  90        return tps65912_device_init(tps65912);
  91}
  92
  93static int tps65912_i2c_remove(struct i2c_client *i2c)
  94{
  95        struct tps65912 *tps65912 = i2c_get_clientdata(i2c);
  96
  97        tps65912_device_exit(tps65912);
  98
  99        return 0;
 100}
 101
 102static const struct i2c_device_id tps65912_i2c_id[] = {
 103        {"tps65912", 0 },
 104        { }
 105};
 106MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id);
 107
 108static struct i2c_driver tps65912_i2c_driver = {
 109        .driver = {
 110                   .name = "tps65912",
 111                   .owner = THIS_MODULE,
 112        },
 113        .probe = tps65912_i2c_probe,
 114        .remove = tps65912_i2c_remove,
 115        .id_table = tps65912_i2c_id,
 116};
 117
 118static int __init tps65912_i2c_init(void)
 119{
 120        int ret;
 121
 122        ret = i2c_add_driver(&tps65912_i2c_driver);
 123        if (ret != 0)
 124                pr_err("Failed to register TPS65912 I2C driver: %d\n", ret);
 125
 126        return ret;
 127}
 128/* init early so consumer devices can complete system boot */
 129subsys_initcall(tps65912_i2c_init);
 130
 131static void __exit tps65912_i2c_exit(void)
 132{
 133        i2c_del_driver(&tps65912_i2c_driver);
 134}
 135module_exit(tps65912_i2c_exit);
 136
 137MODULE_AUTHOR("Margarita Olaya  <magi@slimlogic.co.uk>");
 138MODULE_DESCRIPTION("TPS6591x chip family multi-function driver");
 139MODULE_LICENSE("GPL");
 140