Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
gpio
gpio-mc33880.c
Go to the documentation of this file.
1
/*
2
* MC33880 high-side/low-side switch GPIO driver
3
* Copyright (c) 2009 Intel Corporation
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
*/
18
19
/* Supports:
20
* Freescale MC33880 high-side/low-side switch
21
*/
22
23
#include <
linux/init.h
>
24
#include <
linux/mutex.h
>
25
#include <
linux/spi/spi.h
>
26
#include <
linux/spi/mc33880.h
>
27
#include <
linux/gpio.h
>
28
#include <linux/slab.h>
29
#include <linux/module.h>
30
31
#define DRIVER_NAME "mc33880"
32
33
/*
34
* Pin configurations, see MAX7301 datasheet page 6
35
*/
36
#define PIN_CONFIG_MASK 0x03
37
#define PIN_CONFIG_IN_PULLUP 0x03
38
#define PIN_CONFIG_IN_WO_PULLUP 0x02
39
#define PIN_CONFIG_OUT 0x01
40
41
#define PIN_NUMBER 8
42
43
44
/*
45
* Some registers must be read back to modify.
46
* To save time we cache them here in memory
47
*/
48
struct
mc33880
{
49
struct
mutex
lock
;
/* protect from simultaneous accesses */
50
u8
port_config
;
51
struct
gpio_chip
chip
;
52
struct
spi_device
*
spi
;
53
};
54
55
static
int
mc33880_write_config(
struct
mc33880
*
mc
)
56
{
57
return
spi_write(mc->
spi
, &mc->
port_config
,
sizeof
(mc->
port_config
));
58
}
59
60
61
static
int
__mc33880_set(
struct
mc33880
*
mc
,
unsigned
offset
,
int
value
)
62
{
63
if
(value)
64
mc->
port_config
|= 1 <<
offset
;
65
else
66
mc->
port_config
&= ~(1 <<
offset
);
67
68
return
mc33880_write_config(mc);
69
}
70
71
72
static
void
mc33880_set(
struct
gpio_chip *
chip
,
unsigned
offset,
int
value)
73
{
74
struct
mc33880
*mc =
container_of
(chip,
struct
mc33880
, chip);
75
76
mutex_lock
(&mc->
lock
);
77
78
__mc33880_set(mc, offset, value);
79
80
mutex_unlock
(&mc->
lock
);
81
}
82
83
static
int
__devinit
mc33880_probe(
struct
spi_device
*
spi
)
84
{
85
struct
mc33880
*
mc
;
86
struct
mc33880_platform_data
*
pdata
;
87
int
ret
;
88
89
pdata = spi->
dev
.platform_data;
90
if
(!pdata || !pdata->
base
) {
91
dev_dbg
(&spi->
dev
,
"incorrect or missing platform data\n"
);
92
return
-
EINVAL
;
93
}
94
95
/*
96
* bits_per_word cannot be configured in platform data
97
*/
98
spi->
bits_per_word
= 8;
99
100
ret =
spi_setup
(spi);
101
if
(ret < 0)
102
return
ret
;
103
104
mc = kzalloc(
sizeof
(
struct
mc33880
),
GFP_KERNEL
);
105
if
(!mc)
106
return
-
ENOMEM
;
107
108
mutex_init
(&mc->
lock
);
109
110
dev_set_drvdata
(&spi->
dev
, mc);
111
112
mc->
spi
=
spi
;
113
114
mc->
chip
.label =
DRIVER_NAME
,
115
mc->
chip
.set = mc33880_set;
116
mc->
chip
.base = pdata->
base
;
117
mc->
chip
.ngpio =
PIN_NUMBER
;
118
mc->
chip
.can_sleep = 1;
119
mc->
chip
.dev = &spi->
dev
;
120
mc->
chip
.owner =
THIS_MODULE
;
121
122
mc->
port_config
= 0x00;
123
/* write twice, because during initialisation the first setting
124
* is just for testing SPI communication, and the second is the
125
* "real" configuration
126
*/
127
ret = mc33880_write_config(mc);
128
mc->
port_config
= 0x00;
129
if
(!ret)
130
ret = mc33880_write_config(mc);
131
132
if
(ret) {
133
printk
(
KERN_ERR
"Failed writing to "
DRIVER_NAME
": %d\n"
, ret);
134
goto
exit_destroy;
135
}
136
137
ret =
gpiochip_add
(&mc->
chip
);
138
if
(ret)
139
goto
exit_destroy;
140
141
return
ret
;
142
143
exit_destroy:
144
dev_set_drvdata
(&spi->
dev
,
NULL
);
145
mutex_destroy
(&mc->
lock
);
146
kfree
(mc);
147
return
ret
;
148
}
149
150
static
int
__devexit
mc33880_remove(
struct
spi_device
*spi)
151
{
152
struct
mc33880
*
mc
;
153
int
ret
;
154
155
mc =
dev_get_drvdata
(&spi->
dev
);
156
if
(mc ==
NULL
)
157
return
-
ENODEV
;
158
159
dev_set_drvdata
(&spi->
dev
,
NULL
);
160
161
ret =
gpiochip_remove
(&mc->
chip
);
162
if
(!ret) {
163
mutex_destroy
(&mc->
lock
);
164
kfree
(mc);
165
}
else
166
dev_err
(&spi->
dev
,
"Failed to remove the GPIO controller: %d\n"
,
167
ret);
168
169
return
ret
;
170
}
171
172
static
struct
spi_driver
mc33880_driver = {
173
.driver = {
174
.name =
DRIVER_NAME
,
175
.owner =
THIS_MODULE
,
176
},
177
.probe = mc33880_probe,
178
.remove =
__devexit_p
(mc33880_remove),
179
};
180
181
static
int
__init
mc33880_init(
void
)
182
{
183
return
spi_register_driver
(&mc33880_driver);
184
}
185
/* register after spi postcore initcall and before
186
* subsys initcalls that may rely on these GPIOs
187
*/
188
subsys_initcall
(mc33880_init);
189
190
static
void
__exit
mc33880_exit(
void
)
191
{
192
spi_unregister_driver(&mc33880_driver);
193
}
194
module_exit
(mc33880_exit);
195
196
MODULE_AUTHOR
(
"Mocean Laboratories <
[email protected]
>"
);
197
MODULE_LICENSE
(
"GPL v2"
);
198
Generated on Thu Jan 10 2013 13:30:43 for Linux Kernel by
1.8.2