~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/mfd/tps6507x.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * tps6507x.c  --  TPS6507x chip family multi-function driver
 
3
 *
 
4
 *  Copyright (c) 2010 RidgeRun (todd.fischer@ridgerun.com)
 
5
 *
 
6
 * Author: Todd Fischer
 
7
 *         todd.fischer@ridgerun.com
 
8
 *
 
9
 * Credits:
 
10
 *
 
11
 *    Using code from wm831x-*.c, wm8400-core, Wolfson Microelectronics PLC.
 
12
 *
 
13
 * For licencing details see kernel-base/COPYING
 
14
 *
 
15
 */
 
16
 
 
17
#include <linux/module.h>
 
18
#include <linux/moduleparam.h>
 
19
#include <linux/init.h>
 
20
#include <linux/slab.h>
 
21
#include <linux/i2c.h>
 
22
#include <linux/mfd/core.h>
 
23
#include <linux/mfd/tps6507x.h>
 
24
 
 
25
static struct mfd_cell tps6507x_devs[] = {
 
26
        {
 
27
                .name = "tps6507x-pmic",
 
28
        },
 
29
        {
 
30
                .name = "tps6507x-ts",
 
31
        },
 
32
};
 
33
 
 
34
 
 
35
static int tps6507x_i2c_read_device(struct tps6507x_dev *tps6507x, char reg,
 
36
                                  int bytes, void *dest)
 
37
{
 
38
        struct i2c_client *i2c = tps6507x->i2c_client;
 
39
        struct i2c_msg xfer[2];
 
40
        int ret;
 
41
 
 
42
        /* Write register */
 
43
        xfer[0].addr = i2c->addr;
 
44
        xfer[0].flags = 0;
 
45
        xfer[0].len = 1;
 
46
        xfer[0].buf = &reg;
 
47
 
 
48
        /* Read data */
 
49
        xfer[1].addr = i2c->addr;
 
50
        xfer[1].flags = I2C_M_RD;
 
51
        xfer[1].len = bytes;
 
52
        xfer[1].buf = dest;
 
53
 
 
54
        ret = i2c_transfer(i2c->adapter, xfer, 2);
 
55
        if (ret == 2)
 
56
                ret = 0;
 
57
        else if (ret >= 0)
 
58
                ret = -EIO;
 
59
 
 
60
        return ret;
 
61
}
 
62
 
 
63
static int tps6507x_i2c_write_device(struct tps6507x_dev *tps6507x, char reg,
 
64
                                   int bytes, void *src)
 
65
{
 
66
        struct i2c_client *i2c = tps6507x->i2c_client;
 
67
        /* we add 1 byte for device register */
 
68
        u8 msg[TPS6507X_MAX_REGISTER + 1];
 
69
        int ret;
 
70
 
 
71
        if (bytes > TPS6507X_MAX_REGISTER)
 
72
                return -EINVAL;
 
73
 
 
74
        msg[0] = reg;
 
75
        memcpy(&msg[1], src, bytes);
 
76
 
 
77
        ret = i2c_master_send(i2c, msg, bytes + 1);
 
78
        if (ret < 0)
 
79
                return ret;
 
80
        if (ret != bytes + 1)
 
81
                return -EIO;
 
82
        return 0;
 
83
}
 
84
 
 
85
static int tps6507x_i2c_probe(struct i2c_client *i2c,
 
86
                            const struct i2c_device_id *id)
 
87
{
 
88
        struct tps6507x_dev *tps6507x;
 
89
        int ret = 0;
 
90
 
 
91
        tps6507x = kzalloc(sizeof(struct tps6507x_dev), GFP_KERNEL);
 
92
        if (tps6507x == NULL)
 
93
                return -ENOMEM;
 
94
 
 
95
        i2c_set_clientdata(i2c, tps6507x);
 
96
        tps6507x->dev = &i2c->dev;
 
97
        tps6507x->i2c_client = i2c;
 
98
        tps6507x->read_dev = tps6507x_i2c_read_device;
 
99
        tps6507x->write_dev = tps6507x_i2c_write_device;
 
100
 
 
101
        ret = mfd_add_devices(tps6507x->dev, -1,
 
102
                              tps6507x_devs, ARRAY_SIZE(tps6507x_devs),
 
103
                              NULL, 0);
 
104
 
 
105
        if (ret < 0)
 
106
                goto err;
 
107
 
 
108
        return ret;
 
109
 
 
110
err:
 
111
        mfd_remove_devices(tps6507x->dev);
 
112
        kfree(tps6507x);
 
113
        return ret;
 
114
}
 
115
 
 
116
static int tps6507x_i2c_remove(struct i2c_client *i2c)
 
117
{
 
118
        struct tps6507x_dev *tps6507x = i2c_get_clientdata(i2c);
 
119
 
 
120
        mfd_remove_devices(tps6507x->dev);
 
121
        kfree(tps6507x);
 
122
 
 
123
        return 0;
 
124
}
 
125
 
 
126
static const struct i2c_device_id tps6507x_i2c_id[] = {
 
127
       { "tps6507x", 0 },
 
128
       { }
 
129
};
 
130
MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id);
 
131
 
 
132
 
 
133
static struct i2c_driver tps6507x_i2c_driver = {
 
134
        .driver = {
 
135
                   .name = "tps6507x",
 
136
                   .owner = THIS_MODULE,
 
137
        },
 
138
        .probe = tps6507x_i2c_probe,
 
139
        .remove = tps6507x_i2c_remove,
 
140
        .id_table = tps6507x_i2c_id,
 
141
};
 
142
 
 
143
static int __init tps6507x_i2c_init(void)
 
144
{
 
145
        return i2c_add_driver(&tps6507x_i2c_driver);
 
146
}
 
147
/* init early so consumer devices can complete system boot */
 
148
subsys_initcall(tps6507x_i2c_init);
 
149
 
 
150
static void __exit tps6507x_i2c_exit(void)
 
151
{
 
152
        i2c_del_driver(&tps6507x_i2c_driver);
 
153
}
 
154
module_exit(tps6507x_i2c_exit);
 
155
 
 
156
MODULE_DESCRIPTION("TPS6507x chip family multi-function driver");
 
157
MODULE_LICENSE("GPL");