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

« back to all changes in this revision

Viewing changes to drivers/i2c/busses/i2c-ocores.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-ocores.c: I2C bus driver for OpenCores I2C controller
 
3
 * (http://www.opencores.org/projects.cgi/web/i2c/overview).
 
4
 *
 
5
 * Peter Korsgaard <jacmet@sunsite.dk>
 
6
 *
 
7
 * This file is licensed under the terms of the GNU General Public License
 
8
 * version 2.  This program is licensed "as is" without any warranty of any
 
9
 * kind, whether express or implied.
 
10
 */
 
11
 
 
12
/*
 
13
 * Device tree configuration:
 
14
 *
 
15
 * Required properties:
 
16
 * - compatible      : "opencores,i2c-ocores"
 
17
 * - reg             : bus address start and address range size of device
 
18
 * - interrupts      : interrupt number
 
19
 * - regstep         : size of device registers in bytes
 
20
 * - clock-frequency : frequency of bus clock in Hz
 
21
 * 
 
22
 * Example:
 
23
 *
 
24
 *  i2c0: ocores@a0000000 {
 
25
 *              compatible = "opencores,i2c-ocores";
 
26
 *              reg = <0xa0000000 0x8>;
 
27
 *              interrupts = <10>;
 
28
 *
 
29
 *              regstep = <1>;
 
30
 *              clock-frequency = <20000000>;
 
31
 *
 
32
 * -- Devices connected on this I2C bus get
 
33
 * -- defined here; address- and size-cells
 
34
 * -- apply to these child devices
 
35
 *
 
36
 *              #address-cells = <1>;
 
37
 *              #size-cells = <0>;
 
38
 *
 
39
 *              dummy@60 {
 
40
 *                     compatible = "dummy";
 
41
 *                     reg = <60>;
 
42
 *              };
 
43
 *  };
 
44
 *
 
45
 */
 
46
 
 
47
#include <linux/kernel.h>
 
48
#include <linux/module.h>
 
49
#include <linux/init.h>
 
50
#include <linux/errno.h>
 
51
#include <linux/platform_device.h>
 
52
#include <linux/i2c.h>
 
53
#include <linux/interrupt.h>
 
54
#include <linux/wait.h>
 
55
#include <linux/i2c-ocores.h>
 
56
#include <linux/slab.h>
 
57
#include <linux/io.h>
 
58
 
 
59
struct ocores_i2c {
 
60
        void __iomem *base;
 
61
        int regstep;
 
62
        wait_queue_head_t wait;
 
63
        struct i2c_adapter adap;
 
64
        struct i2c_msg *msg;
 
65
        int pos;
 
66
        int nmsgs;
 
67
        int state; /* see STATE_ */
 
68
        int clock_khz;
 
69
};
 
70
 
 
71
/* registers */
 
72
#define OCI2C_PRELOW            0
 
73
#define OCI2C_PREHIGH           1
 
74
#define OCI2C_CONTROL           2
 
75
#define OCI2C_DATA              3
 
76
#define OCI2C_CMD               4 /* write only */
 
77
#define OCI2C_STATUS            4 /* read only, same address as OCI2C_CMD */
 
78
 
 
79
#define OCI2C_CTRL_IEN          0x40
 
80
#define OCI2C_CTRL_EN           0x80
 
81
 
 
82
#define OCI2C_CMD_START         0x91
 
83
#define OCI2C_CMD_STOP          0x41
 
84
#define OCI2C_CMD_READ          0x21
 
85
#define OCI2C_CMD_WRITE         0x11
 
86
#define OCI2C_CMD_READ_ACK      0x21
 
87
#define OCI2C_CMD_READ_NACK     0x29
 
88
#define OCI2C_CMD_IACK          0x01
 
89
 
 
90
#define OCI2C_STAT_IF           0x01
 
91
#define OCI2C_STAT_TIP          0x02
 
92
#define OCI2C_STAT_ARBLOST      0x20
 
93
#define OCI2C_STAT_BUSY         0x40
 
94
#define OCI2C_STAT_NACK         0x80
 
95
 
 
96
#define STATE_DONE              0
 
97
#define STATE_START             1
 
98
#define STATE_WRITE             2
 
99
#define STATE_READ              3
 
100
#define STATE_ERROR             4
 
101
 
 
102
static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
 
103
{
 
104
        iowrite8(value, i2c->base + reg * i2c->regstep);
 
105
}
 
106
 
 
107
static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg)
 
108
{
 
109
        return ioread8(i2c->base + reg * i2c->regstep);
 
110
}
 
111
 
 
112
static void ocores_process(struct ocores_i2c *i2c)
 
113
{
 
114
        struct i2c_msg *msg = i2c->msg;
 
115
        u8 stat = oc_getreg(i2c, OCI2C_STATUS);
 
116
 
 
117
        if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) {
 
118
                /* stop has been sent */
 
119
                oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 
120
                wake_up(&i2c->wait);
 
121
                return;
 
122
        }
 
123
 
 
124
        /* error? */
 
125
        if (stat & OCI2C_STAT_ARBLOST) {
 
126
                i2c->state = STATE_ERROR;
 
127
                oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
 
128
                return;
 
129
        }
 
130
 
 
131
        if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) {
 
132
                i2c->state =
 
133
                        (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
 
134
 
 
135
                if (stat & OCI2C_STAT_NACK) {
 
136
                        i2c->state = STATE_ERROR;
 
137
                        oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
 
138
                        return;
 
139
                }
 
140
        } else
 
141
                msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA);
 
142
 
 
143
        /* end of msg? */
 
144
        if (i2c->pos == msg->len) {
 
145
                i2c->nmsgs--;
 
146
                i2c->msg++;
 
147
                i2c->pos = 0;
 
148
                msg = i2c->msg;
 
149
 
 
150
                if (i2c->nmsgs) {       /* end? */
 
151
                        /* send start? */
 
152
                        if (!(msg->flags & I2C_M_NOSTART)) {
 
153
                                u8 addr = (msg->addr << 1);
 
154
 
 
155
                                if (msg->flags & I2C_M_RD)
 
156
                                        addr |= 1;
 
157
 
 
158
                                i2c->state = STATE_START;
 
159
 
 
160
                                oc_setreg(i2c, OCI2C_DATA, addr);
 
161
                                oc_setreg(i2c, OCI2C_CMD,  OCI2C_CMD_START);
 
162
                                return;
 
163
                        } else
 
164
                                i2c->state = (msg->flags & I2C_M_RD)
 
165
                                        ? STATE_READ : STATE_WRITE;
 
166
                } else {
 
167
                        i2c->state = STATE_DONE;
 
168
                        oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
 
169
                        return;
 
170
                }
 
171
        }
 
172
 
 
173
        if (i2c->state == STATE_READ) {
 
174
                oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ?
 
175
                          OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK);
 
176
        } else {
 
177
                oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]);
 
178
                oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE);
 
179
        }
 
180
}
 
181
 
 
182
static irqreturn_t ocores_isr(int irq, void *dev_id)
 
183
{
 
184
        struct ocores_i2c *i2c = dev_id;
 
185
 
 
186
        ocores_process(i2c);
 
187
 
 
188
        return IRQ_HANDLED;
 
189
}
 
190
 
 
191
static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 
192
{
 
193
        struct ocores_i2c *i2c = i2c_get_adapdata(adap);
 
194
 
 
195
        i2c->msg = msgs;
 
196
        i2c->pos = 0;
 
197
        i2c->nmsgs = num;
 
198
        i2c->state = STATE_START;
 
199
 
 
200
        oc_setreg(i2c, OCI2C_DATA,
 
201
                        (i2c->msg->addr << 1) |
 
202
                        ((i2c->msg->flags & I2C_M_RD) ? 1:0));
 
203
 
 
204
        oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
 
205
 
 
206
        if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
 
207
                               (i2c->state == STATE_DONE), HZ))
 
208
                return (i2c->state == STATE_DONE) ? num : -EIO;
 
209
        else
 
210
                return -ETIMEDOUT;
 
211
}
 
212
 
 
213
static void ocores_init(struct ocores_i2c *i2c)
 
214
{
 
215
        int prescale;
 
216
        u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
 
217
 
 
218
        /* make sure the device is disabled */
 
219
        oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
 
220
 
 
221
        prescale = (i2c->clock_khz / (5*100)) - 1;
 
222
        oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff);
 
223
        oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8);
 
224
 
 
225
        /* Init the device */
 
226
        oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 
227
        oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN);
 
228
}
 
229
 
 
230
 
 
231
static u32 ocores_func(struct i2c_adapter *adap)
 
232
{
 
233
        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 
234
}
 
235
 
 
236
static const struct i2c_algorithm ocores_algorithm = {
 
237
        .master_xfer    = ocores_xfer,
 
238
        .functionality  = ocores_func,
 
239
};
 
240
 
 
241
static struct i2c_adapter ocores_adapter = {
 
242
        .owner          = THIS_MODULE,
 
243
        .name           = "i2c-ocores",
 
244
        .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
 
245
        .algo           = &ocores_algorithm,
 
246
};
 
247
 
 
248
#ifdef CONFIG_OF
 
249
static int ocores_i2c_of_probe(struct platform_device* pdev,
 
250
                                struct ocores_i2c* i2c)
 
251
{
 
252
        const __be32* val;
 
253
 
 
254
        val = of_get_property(pdev->dev.of_node, "regstep", NULL);
 
255
        if (!val) {
 
256
                dev_err(&pdev->dev, "Missing required parameter 'regstep'");
 
257
                return -ENODEV;
 
258
        }
 
259
        i2c->regstep = be32_to_cpup(val);
 
260
 
 
261
        val = of_get_property(pdev->dev.of_node, "clock-frequency", NULL);
 
262
        if (!val) {
 
263
                dev_err(&pdev->dev,
 
264
                        "Missing required parameter 'clock-frequency'");
 
265
                return -ENODEV;
 
266
        }
 
267
        i2c->clock_khz = be32_to_cpup(val) / 1000;
 
268
 
 
269
        return 0;
 
270
}
 
271
#else
 
272
#define ocores_i2c_of_probe(pdev,i2c) -ENODEV
 
273
#endif
 
274
 
 
275
static int __devinit ocores_i2c_probe(struct platform_device *pdev)
 
276
{
 
277
        struct ocores_i2c *i2c;
 
278
        struct ocores_i2c_platform_data *pdata;
 
279
        struct resource *res, *res2;
 
280
        int ret;
 
281
        int i;
 
282
 
 
283
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
284
        if (!res)
 
285
                return -ENODEV;
 
286
 
 
287
        res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
288
        if (!res2)
 
289
                return -ENODEV;
 
290
 
 
291
        i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
 
292
        if (!i2c)
 
293
                return -ENOMEM;
 
294
 
 
295
        if (!devm_request_mem_region(&pdev->dev, res->start,
 
296
                                     resource_size(res), pdev->name)) {
 
297
                dev_err(&pdev->dev, "Memory region busy\n");
 
298
                return -EBUSY;
 
299
        }
 
300
 
 
301
        i2c->base = devm_ioremap_nocache(&pdev->dev, res->start,
 
302
                                         resource_size(res));
 
303
        if (!i2c->base) {
 
304
                dev_err(&pdev->dev, "Unable to map registers\n");
 
305
                return -EIO;
 
306
        }
 
307
 
 
308
        pdata = pdev->dev.platform_data;
 
309
        if (pdata) {
 
310
                i2c->regstep = pdata->regstep;
 
311
                i2c->clock_khz = pdata->clock_khz;
 
312
        } else {
 
313
                ret = ocores_i2c_of_probe(pdev, i2c);
 
314
                if (ret)
 
315
                        return ret;
 
316
        }
 
317
 
 
318
        ocores_init(i2c);
 
319
 
 
320
        init_waitqueue_head(&i2c->wait);
 
321
        ret = devm_request_irq(&pdev->dev, res2->start, ocores_isr, 0,
 
322
                               pdev->name, i2c);
 
323
        if (ret) {
 
324
                dev_err(&pdev->dev, "Cannot claim IRQ\n");
 
325
                return ret;
 
326
        }
 
327
 
 
328
        /* hook up driver to tree */
 
329
        platform_set_drvdata(pdev, i2c);
 
330
        i2c->adap = ocores_adapter;
 
331
        i2c_set_adapdata(&i2c->adap, i2c);
 
332
        i2c->adap.dev.parent = &pdev->dev;
 
333
        i2c->adap.dev.of_node = pdev->dev.of_node;
 
334
 
 
335
        /* add i2c adapter to i2c tree */
 
336
        ret = i2c_add_adapter(&i2c->adap);
 
337
        if (ret) {
 
338
                dev_err(&pdev->dev, "Failed to add adapter\n");
 
339
                return ret;
 
340
        }
 
341
 
 
342
        /* add in known devices to the bus */
 
343
        if (pdata) {
 
344
                for (i = 0; i < pdata->num_devices; i++)
 
345
                        i2c_new_device(&i2c->adap, pdata->devices + i);
 
346
        }
 
347
 
 
348
        return 0;
 
349
}
 
350
 
 
351
static int __devexit ocores_i2c_remove(struct platform_device* pdev)
 
352
{
 
353
        struct ocores_i2c *i2c = platform_get_drvdata(pdev);
 
354
 
 
355
        /* disable i2c logic */
 
356
        oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL)
 
357
                  & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
 
358
 
 
359
        /* remove adapter & data */
 
360
        i2c_del_adapter(&i2c->adap);
 
361
        platform_set_drvdata(pdev, NULL);
 
362
 
 
363
        return 0;
 
364
}
 
365
 
 
366
#ifdef CONFIG_PM
 
367
static int ocores_i2c_suspend(struct platform_device *pdev, pm_message_t state)
 
368
{
 
369
        struct ocores_i2c *i2c = platform_get_drvdata(pdev);
 
370
        u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
 
371
 
 
372
        /* make sure the device is disabled */
 
373
        oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
 
374
 
 
375
        return 0;
 
376
}
 
377
 
 
378
static int ocores_i2c_resume(struct platform_device *pdev)
 
379
{
 
380
        struct ocores_i2c *i2c = platform_get_drvdata(pdev);
 
381
 
 
382
        ocores_init(i2c);
 
383
 
 
384
        return 0;
 
385
}
 
386
#else
 
387
#define ocores_i2c_suspend      NULL
 
388
#define ocores_i2c_resume       NULL
 
389
#endif
 
390
 
 
391
static struct of_device_id ocores_i2c_match[] = {
 
392
        { .compatible = "opencores,i2c-ocores", },
 
393
        {},
 
394
};
 
395
MODULE_DEVICE_TABLE(of, ocores_i2c_match);
 
396
 
 
397
/* work with hotplug and coldplug */
 
398
MODULE_ALIAS("platform:ocores-i2c");
 
399
 
 
400
static struct platform_driver ocores_i2c_driver = {
 
401
        .probe   = ocores_i2c_probe,
 
402
        .remove  = __devexit_p(ocores_i2c_remove),
 
403
        .suspend = ocores_i2c_suspend,
 
404
        .resume  = ocores_i2c_resume,
 
405
        .driver  = {
 
406
                .owner = THIS_MODULE,
 
407
                .name = "ocores-i2c",
 
408
                .of_match_table = ocores_i2c_match,
 
409
        },
 
410
};
 
411
 
 
412
static int __init ocores_i2c_init(void)
 
413
{
 
414
        return platform_driver_register(&ocores_i2c_driver);
 
415
}
 
416
 
 
417
static void __exit ocores_i2c_exit(void)
 
418
{
 
419
        platform_driver_unregister(&ocores_i2c_driver);
 
420
}
 
421
 
 
422
module_init(ocores_i2c_init);
 
423
module_exit(ocores_i2c_exit);
 
424
 
 
425
MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
 
426
MODULE_DESCRIPTION("OpenCores I2C bus driver");
 
427
MODULE_LICENSE("GPL");