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

« back to all changes in this revision

Viewing changes to drivers/i2c/busses/i2c-pca-platform.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
 *  i2c_pca_platform.c
 
3
 *
 
4
 *  Platform driver for the PCA9564 I2C controller.
 
5
 *
 
6
 *  Copyright (C) 2008 Pengutronix
 
7
 *
 
8
 *  This program is free software; you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License version 2 as
 
10
 *  published by the Free Software Foundation.
 
11
 
 
12
 */
 
13
#include <linux/kernel.h>
 
14
#include <linux/module.h>
 
15
#include <linux/init.h>
 
16
#include <linux/slab.h>
 
17
#include <linux/delay.h>
 
18
#include <linux/jiffies.h>
 
19
#include <linux/errno.h>
 
20
#include <linux/i2c.h>
 
21
#include <linux/interrupt.h>
 
22
#include <linux/platform_device.h>
 
23
#include <linux/i2c-algo-pca.h>
 
24
#include <linux/i2c-pca-platform.h>
 
25
#include <linux/gpio.h>
 
26
#include <linux/io.h>
 
27
 
 
28
#include <asm/irq.h>
 
29
 
 
30
struct i2c_pca_pf_data {
 
31
        void __iomem                    *reg_base;
 
32
        int                             irq;    /* if 0, use polling */
 
33
        int                             gpio;
 
34
        wait_queue_head_t               wait;
 
35
        struct i2c_adapter              adap;
 
36
        struct i2c_algo_pca_data        algo_data;
 
37
        unsigned long                   io_base;
 
38
        unsigned long                   io_size;
 
39
};
 
40
 
 
41
/* Read/Write functions for different register alignments */
 
42
 
 
43
static int i2c_pca_pf_readbyte8(void *pd, int reg)
 
44
{
 
45
        struct i2c_pca_pf_data *i2c = pd;
 
46
        return ioread8(i2c->reg_base + reg);
 
47
}
 
48
 
 
49
static int i2c_pca_pf_readbyte16(void *pd, int reg)
 
50
{
 
51
        struct i2c_pca_pf_data *i2c = pd;
 
52
        return ioread8(i2c->reg_base + reg * 2);
 
53
}
 
54
 
 
55
static int i2c_pca_pf_readbyte32(void *pd, int reg)
 
56
{
 
57
        struct i2c_pca_pf_data *i2c = pd;
 
58
        return ioread8(i2c->reg_base + reg * 4);
 
59
}
 
60
 
 
61
static void i2c_pca_pf_writebyte8(void *pd, int reg, int val)
 
62
{
 
63
        struct i2c_pca_pf_data *i2c = pd;
 
64
        iowrite8(val, i2c->reg_base + reg);
 
65
}
 
66
 
 
67
static void i2c_pca_pf_writebyte16(void *pd, int reg, int val)
 
68
{
 
69
        struct i2c_pca_pf_data *i2c = pd;
 
70
        iowrite8(val, i2c->reg_base + reg * 2);
 
71
}
 
72
 
 
73
static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
 
74
{
 
75
        struct i2c_pca_pf_data *i2c = pd;
 
76
        iowrite8(val, i2c->reg_base + reg * 4);
 
77
}
 
78
 
 
79
 
 
80
static int i2c_pca_pf_waitforcompletion(void *pd)
 
81
{
 
82
        struct i2c_pca_pf_data *i2c = pd;
 
83
        unsigned long timeout;
 
84
        long ret;
 
85
 
 
86
        if (i2c->irq) {
 
87
                ret = wait_event_timeout(i2c->wait,
 
88
                        i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
 
89
                        & I2C_PCA_CON_SI, i2c->adap.timeout);
 
90
        } else {
 
91
                /* Do polling */
 
92
                timeout = jiffies + i2c->adap.timeout;
 
93
                do {
 
94
                        ret = time_before(jiffies, timeout);
 
95
                        if (i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
 
96
                                        & I2C_PCA_CON_SI)
 
97
                                break;
 
98
                        udelay(100);
 
99
                } while (ret);
 
100
        }
 
101
 
 
102
        return ret > 0;
 
103
}
 
104
 
 
105
static void i2c_pca_pf_dummyreset(void *pd)
 
106
{
 
107
        struct i2c_pca_pf_data *i2c = pd;
 
108
        printk(KERN_WARNING "%s: No reset-pin found. Chip may get stuck!\n",
 
109
                i2c->adap.name);
 
110
}
 
111
 
 
112
static void i2c_pca_pf_resetchip(void *pd)
 
113
{
 
114
        struct i2c_pca_pf_data *i2c = pd;
 
115
 
 
116
        gpio_set_value(i2c->gpio, 0);
 
117
        ndelay(100);
 
118
        gpio_set_value(i2c->gpio, 1);
 
119
}
 
120
 
 
121
static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id)
 
122
{
 
123
        struct i2c_pca_pf_data *i2c = dev_id;
 
124
 
 
125
        if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
 
126
                return IRQ_NONE;
 
127
 
 
128
        wake_up(&i2c->wait);
 
129
 
 
130
        return IRQ_HANDLED;
 
131
}
 
132
 
 
133
 
 
134
static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
 
135
{
 
136
        struct i2c_pca_pf_data *i2c;
 
137
        struct resource *res;
 
138
        struct i2c_pca9564_pf_platform_data *platform_data =
 
139
                                pdev->dev.platform_data;
 
140
        int ret = 0;
 
141
        int irq;
 
142
 
 
143
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
144
        irq = platform_get_irq(pdev, 0);
 
145
        /* If irq is 0, we do polling. */
 
146
 
 
147
        if (res == NULL) {
 
148
                ret = -ENODEV;
 
149
                goto e_print;
 
150
        }
 
151
 
 
152
        if (!request_mem_region(res->start, resource_size(res), res->name)) {
 
153
                ret = -ENOMEM;
 
154
                goto e_print;
 
155
        }
 
156
 
 
157
        i2c = kzalloc(sizeof(struct i2c_pca_pf_data), GFP_KERNEL);
 
158
        if (!i2c) {
 
159
                ret = -ENOMEM;
 
160
                goto e_alloc;
 
161
        }
 
162
 
 
163
        init_waitqueue_head(&i2c->wait);
 
164
 
 
165
        i2c->reg_base = ioremap(res->start, resource_size(res));
 
166
        if (!i2c->reg_base) {
 
167
                ret = -ENOMEM;
 
168
                goto e_remap;
 
169
        }
 
170
        i2c->io_base = res->start;
 
171
        i2c->io_size = resource_size(res);
 
172
        i2c->irq = irq;
 
173
 
 
174
        i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
 
175
        i2c->adap.owner = THIS_MODULE;
 
176
        snprintf(i2c->adap.name, sizeof(i2c->adap.name),
 
177
                 "PCA9564/PCA9665 at 0x%08lx",
 
178
                 (unsigned long) res->start);
 
179
        i2c->adap.algo_data = &i2c->algo_data;
 
180
        i2c->adap.dev.parent = &pdev->dev;
 
181
 
 
182
        if (platform_data) {
 
183
                i2c->adap.timeout = platform_data->timeout;
 
184
                i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
 
185
                i2c->gpio = platform_data->gpio;
 
186
        } else {
 
187
                i2c->adap.timeout = HZ;
 
188
                i2c->algo_data.i2c_clock = 59000;
 
189
                i2c->gpio = -1;
 
190
        }
 
191
 
 
192
        i2c->algo_data.data = i2c;
 
193
        i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
 
194
        i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
 
195
 
 
196
        switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
 
197
        case IORESOURCE_MEM_32BIT:
 
198
                i2c->algo_data.write_byte = i2c_pca_pf_writebyte32;
 
199
                i2c->algo_data.read_byte = i2c_pca_pf_readbyte32;
 
200
                break;
 
201
        case IORESOURCE_MEM_16BIT:
 
202
                i2c->algo_data.write_byte = i2c_pca_pf_writebyte16;
 
203
                i2c->algo_data.read_byte = i2c_pca_pf_readbyte16;
 
204
                break;
 
205
        case IORESOURCE_MEM_8BIT:
 
206
        default:
 
207
                i2c->algo_data.write_byte = i2c_pca_pf_writebyte8;
 
208
                i2c->algo_data.read_byte = i2c_pca_pf_readbyte8;
 
209
                break;
 
210
        }
 
211
 
 
212
        /* Use gpio_is_valid() when in mainline */
 
213
        if (i2c->gpio > -1) {
 
214
                ret = gpio_request(i2c->gpio, i2c->adap.name);
 
215
                if (ret == 0) {
 
216
                        gpio_direction_output(i2c->gpio, 1);
 
217
                        i2c->algo_data.reset_chip = i2c_pca_pf_resetchip;
 
218
                } else {
 
219
                        printk(KERN_WARNING "%s: Registering gpio failed!\n",
 
220
                                i2c->adap.name);
 
221
                        i2c->gpio = ret;
 
222
                }
 
223
        }
 
224
 
 
225
        if (irq) {
 
226
                ret = request_irq(irq, i2c_pca_pf_handler,
 
227
                        IRQF_TRIGGER_FALLING, pdev->name, i2c);
 
228
                if (ret)
 
229
                        goto e_reqirq;
 
230
        }
 
231
 
 
232
        if (i2c_pca_add_numbered_bus(&i2c->adap) < 0) {
 
233
                ret = -ENODEV;
 
234
                goto e_adapt;
 
235
        }
 
236
 
 
237
        platform_set_drvdata(pdev, i2c);
 
238
 
 
239
        printk(KERN_INFO "%s registered.\n", i2c->adap.name);
 
240
 
 
241
        return 0;
 
242
 
 
243
e_adapt:
 
244
        if (irq)
 
245
                free_irq(irq, i2c);
 
246
e_reqirq:
 
247
        if (i2c->gpio > -1)
 
248
                gpio_free(i2c->gpio);
 
249
 
 
250
        iounmap(i2c->reg_base);
 
251
e_remap:
 
252
        kfree(i2c);
 
253
e_alloc:
 
254
        release_mem_region(res->start, resource_size(res));
 
255
e_print:
 
256
        printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret);
 
257
        return ret;
 
258
}
 
259
 
 
260
static int __devexit i2c_pca_pf_remove(struct platform_device *pdev)
 
261
{
 
262
        struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
 
263
        platform_set_drvdata(pdev, NULL);
 
264
 
 
265
        i2c_del_adapter(&i2c->adap);
 
266
 
 
267
        if (i2c->irq)
 
268
                free_irq(i2c->irq, i2c);
 
269
 
 
270
        if (i2c->gpio > -1)
 
271
                gpio_free(i2c->gpio);
 
272
 
 
273
        iounmap(i2c->reg_base);
 
274
        release_mem_region(i2c->io_base, i2c->io_size);
 
275
        kfree(i2c);
 
276
 
 
277
        return 0;
 
278
}
 
279
 
 
280
static struct platform_driver i2c_pca_pf_driver = {
 
281
        .probe = i2c_pca_pf_probe,
 
282
        .remove = __devexit_p(i2c_pca_pf_remove),
 
283
        .driver = {
 
284
                .name = "i2c-pca-platform",
 
285
                .owner = THIS_MODULE,
 
286
        },
 
287
};
 
288
 
 
289
static int __init i2c_pca_pf_init(void)
 
290
{
 
291
        return platform_driver_register(&i2c_pca_pf_driver);
 
292
}
 
293
 
 
294
static void __exit i2c_pca_pf_exit(void)
 
295
{
 
296
        platform_driver_unregister(&i2c_pca_pf_driver);
 
297
}
 
298
 
 
299
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
 
300
MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
 
301
MODULE_LICENSE("GPL");
 
302
 
 
303
module_init(i2c_pca_pf_init);
 
304
module_exit(i2c_pca_pf_exit);
 
305