Skip to content

Commit 61fd152

Browse files
Alan Coxgregkh
authored andcommitted
serial: max3107: Abstract out the platform specific bits
At the moment there is only one platform type supported and there is is hard wired, but with these changes the infrastructure is now there for anyone else to provide methods for their hardware. Signed-off-by: Alan Cox <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 44318fe commit 61fd152

File tree

6 files changed

+531
-337
lines changed

6 files changed

+531
-337
lines changed

drivers/serial/Kconfig

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -542,20 +542,29 @@ config SERIAL_S5PV210
542542
help
543543
Serial port support for Samsung's S5P Family of SoC's
544544

545+
546+
config SERIAL_MAX3100
547+
tristate "MAX3100 support"
548+
depends on SPI
549+
select SERIAL_CORE
550+
help
551+
MAX3100 chip support
552+
545553
config SERIAL_MAX3107
546554
tristate "MAX3107 support"
547-
depends on SPI && GPIOLIB
555+
depends on SPI
548556
select SERIAL_CORE
549-
default y
550557
help
551558
MAX3107 chip support
552559

553-
config SERIAL_MAX3100
554-
tristate "MAX3100 support"
555-
depends on SPI
560+
config SERIAL_MAX3107_AAVA
561+
tristate "MAX3107 AAVA platform support"
562+
depends on X86_MRST && SERIAL_MAX3107 && GPIOLIB
556563
select SERIAL_CORE
557564
help
558-
MAX3100 chip support
565+
Support for the MAX3107 chip configuration found on the AAVA
566+
platform. Includes the extra initialisation and GPIO support
567+
neded for this device.
559568

560569
config SERIAL_DZ
561570
bool "DECstation DZ serial driver"

drivers/serial/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
4747
obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
4848
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
4949
obj-$(CONFIG_SERIAL_MAX3107) += max3107.o
50+
obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
5051
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
5152
obj-$(CONFIG_SERIAL_MUX) += mux.o
5253
obj-$(CONFIG_SERIAL_68328) += 68328serial.o

drivers/serial/max3107-aava.c

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
/*
2+
* max3107.c - spi uart protocol driver for Maxim 3107
3+
* Based on max3100.c
4+
* by Christian Pellegrin <[email protected]>
5+
* and max3110.c
6+
* by Feng Tang <[email protected]>
7+
*
8+
* Copyright (C) Aavamobile 2009
9+
*
10+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11+
*
12+
* This program is free software; you can redistribute it and/or modify
13+
* it under the terms of the GNU General Public License as published by
14+
* the Free Software Foundation; either version 2 of the License, or
15+
* (at your option) any later version.
16+
*
17+
* This program is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU General Public License
23+
* along with this program; if not, write to the Free Software
24+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25+
*
26+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27+
*
28+
*/
29+
30+
#include <linux/delay.h>
31+
#include <linux/device.h>
32+
#include <linux/serial_core.h>
33+
#include <linux/serial.h>
34+
#include <linux/spi/spi.h>
35+
#include <linux/freezer.h>
36+
#include <linux/platform_device.h>
37+
#include <linux/gpio.h>
38+
#include <linux/sfi.h>
39+
#include <asm/mrst.h>
40+
#include "max3107.h"
41+
42+
/* GPIO direction to input function */
43+
static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
44+
{
45+
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
46+
u16 buf[1]; /* Buffer for SPI transfer */
47+
48+
if (offset >= MAX3107_GPIO_COUNT) {
49+
dev_err(&s->spi->dev, "Invalid GPIO\n");
50+
return -EINVAL;
51+
}
52+
53+
/* Read current GPIO configuration register */
54+
buf[0] = MAX3107_GPIOCFG_REG;
55+
/* Perform SPI transfer */
56+
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) {
57+
dev_err(&s->spi->dev, "SPI transfer GPIO read failed\n");
58+
return -EIO;
59+
}
60+
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
61+
62+
/* Set GPIO to input */
63+
buf[0] &= ~(0x0001 << offset);
64+
65+
/* Write new GPIO configuration register value */
66+
buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG);
67+
/* Perform SPI transfer */
68+
if (max3107_rw(s, (u8 *)buf, NULL, 2)) {
69+
dev_err(&s->spi->dev, "SPI transfer GPIO write failed\n");
70+
return -EIO;
71+
}
72+
return 0;
73+
}
74+
75+
/* GPIO direction to output function */
76+
static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset,
77+
int value)
78+
{
79+
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
80+
u16 buf[2]; /* Buffer for SPI transfers */
81+
82+
if (offset >= MAX3107_GPIO_COUNT) {
83+
dev_err(&s->spi->dev, "Invalid GPIO\n");
84+
return -EINVAL;
85+
}
86+
87+
/* Read current GPIO configuration and data registers */
88+
buf[0] = MAX3107_GPIOCFG_REG;
89+
buf[1] = MAX3107_GPIODATA_REG;
90+
/* Perform SPI transfer */
91+
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) {
92+
dev_err(&s->spi->dev, "SPI transfer gpio failed\n");
93+
return -EIO;
94+
}
95+
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
96+
buf[1] &= MAX3107_SPI_RX_DATA_MASK;
97+
98+
/* Set GPIO to output */
99+
buf[0] |= (0x0001 << offset);
100+
/* Set value */
101+
if (value)
102+
buf[1] |= (0x0001 << offset);
103+
else
104+
buf[1] &= ~(0x0001 << offset);
105+
106+
/* Write new GPIO configuration and data register values */
107+
buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG);
108+
buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG);
109+
/* Perform SPI transfer */
110+
if (max3107_rw(s, (u8 *)buf, NULL, 4)) {
111+
dev_err(&s->spi->dev,
112+
"SPI transfer for GPIO conf data w failed\n");
113+
return -EIO;
114+
}
115+
return 0;
116+
}
117+
118+
/* GPIO value query function */
119+
static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset)
120+
{
121+
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
122+
u16 buf[1]; /* Buffer for SPI transfer */
123+
124+
if (offset >= MAX3107_GPIO_COUNT) {
125+
dev_err(&s->spi->dev, "Invalid GPIO\n");
126+
return -EINVAL;
127+
}
128+
129+
/* Read current GPIO data register */
130+
buf[0] = MAX3107_GPIODATA_REG;
131+
/* Perform SPI transfer */
132+
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) {
133+
dev_err(&s->spi->dev, "SPI transfer GPIO data r failed\n");
134+
return -EIO;
135+
}
136+
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
137+
138+
/* Return value */
139+
return buf[0] & (0x0001 << offset);
140+
}
141+
142+
/* GPIO value set function */
143+
static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
144+
{
145+
struct max3107_port *s = container_of(chip, struct max3107_port, chip);
146+
u16 buf[2]; /* Buffer for SPI transfers */
147+
148+
if (offset >= MAX3107_GPIO_COUNT) {
149+
dev_err(&s->spi->dev, "Invalid GPIO\n");
150+
return;
151+
}
152+
153+
/* Read current GPIO configuration registers*/
154+
buf[0] = MAX3107_GPIODATA_REG;
155+
buf[1] = MAX3107_GPIOCFG_REG;
156+
/* Perform SPI transfer */
157+
if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) {
158+
dev_err(&s->spi->dev,
159+
"SPI transfer for GPIO data and config read failed\n");
160+
return;
161+
}
162+
buf[0] &= MAX3107_SPI_RX_DATA_MASK;
163+
buf[1] &= MAX3107_SPI_RX_DATA_MASK;
164+
165+
if (!(buf[1] & (0x0001 << offset))) {
166+
/* Configured as input, can't set value */
167+
dev_warn(&s->spi->dev,
168+
"Trying to set value for input GPIO\n");
169+
return;
170+
}
171+
172+
/* Set value */
173+
if (value)
174+
buf[0] |= (0x0001 << offset);
175+
else
176+
buf[0] &= ~(0x0001 << offset);
177+
178+
/* Write new GPIO data register value */
179+
buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG);
180+
/* Perform SPI transfer */
181+
if (max3107_rw(s, (u8 *)buf, NULL, 2))
182+
dev_err(&s->spi->dev, "SPI transfer GPIO data w failed\n");
183+
}
184+
185+
/* GPIO chip data */
186+
static struct gpio_chip max3107_gpio_chip = {
187+
.owner = THIS_MODULE,
188+
.direction_input = max3107_gpio_direction_in,
189+
.direction_output = max3107_gpio_direction_out,
190+
.get = max3107_gpio_get,
191+
.set = max3107_gpio_set,
192+
.can_sleep = 1,
193+
.base = MAX3107_GPIO_BASE,
194+
.ngpio = MAX3107_GPIO_COUNT,
195+
};
196+
197+
/**
198+
* max3107_aava_reset - reset on AAVA systems
199+
* @spi: The SPI device we are probing
200+
*
201+
* Reset the device ready for probing.
202+
*/
203+
204+
static int max3107_aava_reset(struct spi_device *spi)
205+
{
206+
/* Reset the chip */
207+
if (gpio_request(MAX3107_RESET_GPIO, "max3107")) {
208+
pr_err("Requesting RESET GPIO failed\n");
209+
return -EIO;
210+
}
211+
if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) {
212+
pr_err("Setting RESET GPIO to 0 failed\n");
213+
gpio_free(MAX3107_RESET_GPIO);
214+
return -EIO;
215+
}
216+
msleep(MAX3107_RESET_DELAY);
217+
if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) {
218+
pr_err("Setting RESET GPIO to 1 failed\n");
219+
gpio_free(MAX3107_RESET_GPIO);
220+
return -EIO;
221+
}
222+
gpio_free(MAX3107_RESET_GPIO);
223+
msleep(MAX3107_WAKEUP_DELAY);
224+
return 0;
225+
}
226+
227+
static int max3107_aava_configure(struct max3107_port *s)
228+
{
229+
int retval;
230+
231+
/* Initialize GPIO chip data */
232+
s->chip = max3107_gpio_chip;
233+
s->chip.label = s->spi->modalias;
234+
s->chip.dev = &s->spi->dev;
235+
236+
/* Add GPIO chip */
237+
retval = gpiochip_add(&s->chip);
238+
if (retval) {
239+
dev_err(&s->spi->dev, "Adding GPIO chip failed\n");
240+
return retval;
241+
}
242+
243+
/* Temporary fix for EV2 boot problems, set modem reset to 0 */
244+
max3107_gpio_direction_out(&s->chip, 3, 0);
245+
return 0;
246+
}
247+
248+
#if 0
249+
/* This will get enabled once we have the board stuff merged for this
250+
specific case */
251+
252+
static const struct baud_table brg13_ext[] = {
253+
{ 300, MAX3107_BRG13_B300 },
254+
{ 600, MAX3107_BRG13_B600 },
255+
{ 1200, MAX3107_BRG13_B1200 },
256+
{ 2400, MAX3107_BRG13_B2400 },
257+
{ 4800, MAX3107_BRG13_B4800 },
258+
{ 9600, MAX3107_BRG13_B9600 },
259+
{ 19200, MAX3107_BRG13_B19200 },
260+
{ 57600, MAX3107_BRG13_B57600 },
261+
{ 115200, MAX3107_BRG13_B115200 },
262+
{ 230400, MAX3107_BRG13_B230400 },
263+
{ 460800, MAX3107_BRG13_B460800 },
264+
{ 921600, MAX3107_BRG13_B921600 },
265+
{ 0, 0 }
266+
};
267+
268+
static void max3107_aava_init(struct max3107_port *s)
269+
{
270+
/*override for AAVA SC specific*/
271+
if (mrst_platform_id() == MRST_PLATFORM_AAVA_SC) {
272+
if (get_koski_build_id() <= KOSKI_EV2)
273+
if (s->ext_clk) {
274+
s->brg_cfg = MAX3107_BRG13_B9600;
275+
s->baud_tbl = (struct baud_table *)brg13_ext;
276+
}
277+
}
278+
}
279+
#endif
280+
281+
static int __devexit max3107_aava_remove(struct spi_device *spi)
282+
{
283+
struct max3107_port *s = dev_get_drvdata(&spi->dev);
284+
285+
/* Remove GPIO chip */
286+
if (gpiochip_remove(&s->chip))
287+
dev_warn(&spi->dev, "Removing GPIO chip failed\n");
288+
289+
/* Then do the default remove */
290+
return max3107_remove(spi);
291+
}
292+
293+
/* Platform data */
294+
static struct max3107_plat aava_plat_data = {
295+
.loopback = 0,
296+
.ext_clk = 1,
297+
/* .init = max3107_aava_init, */
298+
.configure = max3107_aava_configure,
299+
.hw_suspend = max3107_hw_susp,
300+
.polled_mode = 0,
301+
.poll_time = 0,
302+
};
303+
304+
305+
static int __devinit max3107_probe_aava(struct spi_device *spi)
306+
{
307+
int err = max3107_aava_reset(spi);
308+
if (err < 0)
309+
return err;
310+
return max3107_probe(spi, &aava_plat_data);
311+
}
312+
313+
/* Spi driver data */
314+
static struct spi_driver max3107_driver = {
315+
.driver = {
316+
.name = "aava-max3107",
317+
.bus = &spi_bus_type,
318+
.owner = THIS_MODULE,
319+
},
320+
.probe = max3107_probe_aava,
321+
.remove = __devexit_p(max3107_aava_remove),
322+
.suspend = max3107_suspend,
323+
.resume = max3107_resume,
324+
};
325+
326+
/* Driver init function */
327+
static int __init max3107_init(void)
328+
{
329+
return spi_register_driver(&max3107_driver);
330+
}
331+
332+
/* Driver exit function */
333+
static void __exit max3107_exit(void)
334+
{
335+
spi_unregister_driver(&max3107_driver);
336+
}
337+
338+
module_init(max3107_init);
339+
module_exit(max3107_exit);
340+
341+
MODULE_DESCRIPTION("MAX3107 driver");
342+
MODULE_AUTHOR("Aavamobile");
343+
MODULE_ALIAS("aava-max3107-spi");
344+
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)