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

« back to all changes in this revision

Viewing changes to drivers/mfd/tps65912-spi.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
 * tps65912-spi.c  --  SPI 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/spi/spi.h>
 
22
#include <linux/mfd/core.h>
 
23
#include <linux/mfd/tps65912.h>
 
24
 
 
25
static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr,
 
26
                                                        int bytes, void *src)
 
27
{
 
28
        struct spi_device *spi = tps65912->control_data;
 
29
        u8 *data = (u8 *) src;
 
30
        int ret;
 
31
        /* bit 23 is the read/write bit */
 
32
        unsigned long spi_data = 1 << 23 | addr << 15 | *data;
 
33
        struct spi_transfer xfer;
 
34
        struct spi_message msg;
 
35
        u32 tx_buf, rx_buf;
 
36
 
 
37
        tx_buf = spi_data;
 
38
        rx_buf = 0;
 
39
 
 
40
        xfer.tx_buf     = &tx_buf;
 
41
        xfer.rx_buf     = NULL;
 
42
        xfer.len        = sizeof(unsigned long);
 
43
        xfer.bits_per_word = 24;
 
44
 
 
45
        spi_message_init(&msg);
 
46
        spi_message_add_tail(&xfer, &msg);
 
47
 
 
48
        ret = spi_sync(spi, &msg);
 
49
        return ret;
 
50
}
 
51
 
 
52
static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr,
 
53
                                                        int bytes, void *dest)
 
54
{
 
55
        struct spi_device *spi = tps65912->control_data;
 
56
        /* bit 23 is the read/write bit */
 
57
        unsigned long spi_data = 0 << 23 | addr << 15;
 
58
        struct spi_transfer xfer;
 
59
        struct spi_message msg;
 
60
        int ret;
 
61
        u8 *data = (u8 *) dest;
 
62
        u32 tx_buf, rx_buf;
 
63
 
 
64
        tx_buf = spi_data;
 
65
        rx_buf = 0;
 
66
 
 
67
        xfer.tx_buf     = &tx_buf;
 
68
        xfer.rx_buf     = &rx_buf;
 
69
        xfer.len        = sizeof(unsigned long);
 
70
        xfer.bits_per_word = 24;
 
71
 
 
72
        spi_message_init(&msg);
 
73
        spi_message_add_tail(&xfer, &msg);
 
74
 
 
75
        if (spi == NULL)
 
76
                return 0;
 
77
 
 
78
        ret = spi_sync(spi, &msg);
 
79
        if (ret == 0)
 
80
                *data = (u8) (rx_buf & 0xFF);
 
81
        return ret;
 
82
}
 
83
 
 
84
static int __devinit tps65912_spi_probe(struct spi_device *spi)
 
85
{
 
86
        struct tps65912 *tps65912;
 
87
 
 
88
        tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL);
 
89
        if (tps65912 == NULL)
 
90
                return -ENOMEM;
 
91
 
 
92
        tps65912->dev = &spi->dev;
 
93
        tps65912->control_data = spi;
 
94
        tps65912->read = tps65912_spi_read;
 
95
        tps65912->write = tps65912_spi_write;
 
96
 
 
97
        spi_set_drvdata(spi, tps65912);
 
98
 
 
99
        return tps65912_device_init(tps65912);
 
100
}
 
101
 
 
102
static int __devexit tps65912_spi_remove(struct spi_device *spi)
 
103
{
 
104
        struct tps65912 *tps65912 = spi_get_drvdata(spi);
 
105
 
 
106
        tps65912_device_exit(tps65912);
 
107
 
 
108
        return 0;
 
109
}
 
110
 
 
111
static struct spi_driver tps65912_spi_driver = {
 
112
        .driver = {
 
113
                .name = "tps65912",
 
114
                .bus = &spi_bus_type,
 
115
                .owner = THIS_MODULE,
 
116
        },
 
117
        .probe  = tps65912_spi_probe,
 
118
        .remove = __devexit_p(tps65912_spi_remove),
 
119
};
 
120
 
 
121
static int __init tps65912_spi_init(void)
 
122
{
 
123
        int ret;
 
124
 
 
125
        ret = spi_register_driver(&tps65912_spi_driver);
 
126
        if (ret != 0)
 
127
                pr_err("Failed to register TPS65912 SPI driver: %d\n", ret);
 
128
 
 
129
        return 0;
 
130
}
 
131
/* init early so consumer devices can complete system boot */
 
132
subsys_initcall(tps65912_spi_init);
 
133
 
 
134
static void __exit tps65912_spi_exit(void)
 
135
{
 
136
        spi_unregister_driver(&tps65912_spi_driver);
 
137
}
 
138
module_exit(tps65912_spi_exit);
 
139
 
 
140
MODULE_AUTHOR("Margarita Olaya  <magi@slimlogic.co.uk>");
 
141
MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd");
 
142
MODULE_LICENSE("GPL");