Skip to content

Commit b9facea

Browse files
committed
Merge remote-tracking branches 'spi/topic/lp8841', 'spi/topic/msg', 'spi/topic/pl022' and 'spi/topic/pxa2xx' into spi-next
5 parents f91c75d + 14a2042 + 10f11a2 + 22640c8 + 5907450 commit b9facea

File tree

12 files changed

+881
-96
lines changed

12 files changed

+881
-96
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
* ICP DAS LP-8841 SPI Controller for RTC
2+
3+
ICP DAS LP-8841 contains a DS-1302 RTC. RTC is connected to an IO
4+
memory register, which acts as an SPI master device.
5+
6+
The device uses the standard MicroWire half-duplex transfer timing.
7+
Master output is set on low clock and sensed by the RTC on the rising
8+
edge. Master input is set by the RTC on the trailing edge and is sensed
9+
by the master on low clock.
10+
11+
Required properties:
12+
13+
- #address-cells: should be 1
14+
15+
- #size-cells: should be 0
16+
17+
- compatible: should be "icpdas,lp8841-spi-rtc"
18+
19+
- reg: should provide IO memory address
20+
21+
Requirements to SPI slave nodes:
22+
23+
- There can be only one slave device.
24+
25+
- The spi slave node should claim the following flags which are
26+
required by the spi controller.
27+
28+
- spi-3wire: The master itself has only 3 wire. It cannor work in
29+
full duplex mode.
30+
31+
- spi-cs-high: DS-1302 has active high chip select line. The master
32+
doesn't support active low.
33+
34+
- spi-lsb-first: DS-1302 requires least significant bit first
35+
transfers. The master only support this type of bit ordering.
36+
37+
38+
Example:
39+
40+
spi@901c {
41+
#address-cells = <1>;
42+
#size-cells = <0>;
43+
compatible = "icpdas,lp8841-spi-rtc";
44+
reg = <0x901c 0x1>;
45+
46+
rtc@0 {
47+
compatible = "maxim,ds1302";
48+
reg = <0>;
49+
spi-max-frequency = <500000>;
50+
spi-3wire;
51+
spi-lsb-first;
52+
spi-cs-high;
53+
};
54+
};

drivers/spi/Kconfig

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,16 @@ config SPI_LM70_LLP
294294
which interfaces to an LM70 temperature sensor using
295295
a parallel port.
296296

297+
config SPI_LP8841_RTC
298+
tristate "ICP DAS LP-8841 SPI Controller for RTC"
299+
depends on MACH_PXA27X_DT || COMPILE_TEST
300+
help
301+
This driver provides an SPI master device to drive Maxim
302+
DS-1302 real time clock.
303+
304+
Say N here unless you plan to run the kernel on an ICP DAS
305+
LP-8x4x industrial computer.
306+
297307
config SPI_MPC52xx
298308
tristate "Freescale MPC52xx SPI (non-PSC) controller support"
299309
depends on PPC_MPC52xx
@@ -445,10 +455,6 @@ config SPI_PPC4xx
445455
help
446456
This selects a driver for the PPC4xx SPI Controller.
447457

448-
config SPI_PXA2XX_DMA
449-
def_bool y
450-
depends on SPI_PXA2XX
451-
452458
config SPI_PXA2XX
453459
tristate "PXA2xx SSP SPI master"
454460
depends on (ARCH_PXA || PCI || ACPI)

drivers/spi/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
4747
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
4848
obj-$(CONFIG_SPI_IMX) += spi-imx.o
4949
obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
50+
obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
5051
obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
5152
obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
5253
obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
@@ -63,8 +64,7 @@ obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o
6364
obj-$(CONFIG_SPI_ORION) += spi-orion.o
6465
obj-$(CONFIG_SPI_PL022) += spi-pl022.o
6566
obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o
66-
spi-pxa2xx-platform-objs := spi-pxa2xx.o
67-
spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
67+
spi-pxa2xx-platform-objs := spi-pxa2xx.o spi-pxa2xx-dma.o
6868
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
6969
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
7070
obj-$(CONFIG_SPI_QUP) += spi-qup.o

drivers/spi/spi-lp8841-rtc.c

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
/*
2+
* SPI master driver for ICP DAS LP-8841 RTC
3+
*
4+
* Copyright (C) 2016 Sergei Ianovich
5+
*
6+
* based on
7+
*
8+
* Dallas DS1302 RTC Support
9+
* Copyright (C) 2002 David McCullough
10+
* Copyright (C) 2003 - 2007 Paul Mundt
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+
#include <linux/delay.h>
23+
#include <linux/kernel.h>
24+
#include <linux/module.h>
25+
#include <linux/platform_device.h>
26+
#include <linux/of.h>
27+
#include <linux/of_device.h>
28+
#include <linux/spi/spi.h>
29+
30+
#define DRIVER_NAME "spi_lp8841_rtc"
31+
32+
#define SPI_LP8841_RTC_CE 0x01
33+
#define SPI_LP8841_RTC_CLK 0x02
34+
#define SPI_LP8841_RTC_nWE 0x04
35+
#define SPI_LP8841_RTC_MOSI 0x08
36+
#define SPI_LP8841_RTC_MISO 0x01
37+
38+
/*
39+
* REVISIT If there is support for SPI_3WIRE and SPI_LSB_FIRST in SPI
40+
* GPIO driver, this SPI driver can be replaced by a simple GPIO driver
41+
* providing 3 GPIO pins.
42+
*/
43+
44+
struct spi_lp8841_rtc {
45+
void *iomem;
46+
unsigned long state;
47+
};
48+
49+
static inline void
50+
setsck(struct spi_lp8841_rtc *data, int is_on)
51+
{
52+
if (is_on)
53+
data->state |= SPI_LP8841_RTC_CLK;
54+
else
55+
data->state &= ~SPI_LP8841_RTC_CLK;
56+
writeb(data->state, data->iomem);
57+
}
58+
59+
static inline void
60+
setmosi(struct spi_lp8841_rtc *data, int is_on)
61+
{
62+
if (is_on)
63+
data->state |= SPI_LP8841_RTC_MOSI;
64+
else
65+
data->state &= ~SPI_LP8841_RTC_MOSI;
66+
writeb(data->state, data->iomem);
67+
}
68+
69+
static inline int
70+
getmiso(struct spi_lp8841_rtc *data)
71+
{
72+
return ioread8(data->iomem) & SPI_LP8841_RTC_MISO;
73+
}
74+
75+
static inline u32
76+
bitbang_txrx_be_cpha0_lsb(struct spi_lp8841_rtc *data,
77+
unsigned usecs, unsigned cpol, unsigned flags,
78+
u32 word, u8 bits)
79+
{
80+
/* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */
81+
82+
u32 shift = 32 - bits;
83+
/* clock starts at inactive polarity */
84+
for (; likely(bits); bits--) {
85+
86+
/* setup LSB (to slave) on leading edge */
87+
if ((flags & SPI_MASTER_NO_TX) == 0)
88+
setmosi(data, (word & 1));
89+
90+
usleep_range(usecs, usecs + 1); /* T(setup) */
91+
92+
/* sample LSB (from slave) on trailing edge */
93+
word >>= 1;
94+
if ((flags & SPI_MASTER_NO_RX) == 0)
95+
word |= (getmiso(data) << 31);
96+
97+
setsck(data, !cpol);
98+
usleep_range(usecs, usecs + 1);
99+
100+
setsck(data, cpol);
101+
}
102+
103+
word >>= shift;
104+
return word;
105+
}
106+
107+
static int
108+
spi_lp8841_rtc_transfer_one(struct spi_master *master,
109+
struct spi_device *spi,
110+
struct spi_transfer *t)
111+
{
112+
struct spi_lp8841_rtc *data = spi_master_get_devdata(master);
113+
unsigned count = t->len;
114+
const u8 *tx = t->tx_buf;
115+
u8 *rx = t->rx_buf;
116+
u8 word = 0;
117+
int ret = 0;
118+
119+
if (tx) {
120+
data->state &= ~SPI_LP8841_RTC_nWE;
121+
writeb(data->state, data->iomem);
122+
while (likely(count > 0)) {
123+
word = *tx++;
124+
bitbang_txrx_be_cpha0_lsb(data, 1, 0,
125+
SPI_MASTER_NO_RX, word, 8);
126+
count--;
127+
}
128+
} else if (rx) {
129+
data->state |= SPI_LP8841_RTC_nWE;
130+
writeb(data->state, data->iomem);
131+
while (likely(count > 0)) {
132+
word = bitbang_txrx_be_cpha0_lsb(data, 1, 0,
133+
SPI_MASTER_NO_TX, word, 8);
134+
*rx++ = word;
135+
count--;
136+
}
137+
} else {
138+
ret = -EINVAL;
139+
}
140+
141+
spi_finalize_current_transfer(master);
142+
143+
return ret;
144+
}
145+
146+
static void
147+
spi_lp8841_rtc_set_cs(struct spi_device *spi, bool enable)
148+
{
149+
struct spi_lp8841_rtc *data = spi_master_get_devdata(spi->master);
150+
151+
data->state = 0;
152+
writeb(data->state, data->iomem);
153+
if (enable) {
154+
usleep_range(4, 5);
155+
data->state |= SPI_LP8841_RTC_CE;
156+
writeb(data->state, data->iomem);
157+
usleep_range(4, 5);
158+
}
159+
}
160+
161+
static int
162+
spi_lp8841_rtc_setup(struct spi_device *spi)
163+
{
164+
if ((spi->mode & SPI_CS_HIGH) == 0) {
165+
dev_err(&spi->dev, "unsupported active low chip select\n");
166+
return -EINVAL;
167+
}
168+
169+
if ((spi->mode & SPI_LSB_FIRST) == 0) {
170+
dev_err(&spi->dev, "unsupported MSB first mode\n");
171+
return -EINVAL;
172+
}
173+
174+
if ((spi->mode & SPI_3WIRE) == 0) {
175+
dev_err(&spi->dev, "unsupported wiring. 3 wires required\n");
176+
return -EINVAL;
177+
}
178+
179+
return 0;
180+
}
181+
182+
#ifdef CONFIG_OF
183+
static const struct of_device_id spi_lp8841_rtc_dt_ids[] = {
184+
{ .compatible = "icpdas,lp8841-spi-rtc" },
185+
{ }
186+
};
187+
188+
MODULE_DEVICE_TABLE(of, spi_lp8841_rtc_dt_ids);
189+
#endif
190+
191+
static int
192+
spi_lp8841_rtc_probe(struct platform_device *pdev)
193+
{
194+
int ret;
195+
struct spi_master *master;
196+
struct spi_lp8841_rtc *data;
197+
void *iomem;
198+
199+
master = spi_alloc_master(&pdev->dev, sizeof(*data));
200+
if (!master)
201+
return -ENOMEM;
202+
platform_set_drvdata(pdev, master);
203+
204+
master->flags = SPI_MASTER_HALF_DUPLEX;
205+
master->mode_bits = SPI_CS_HIGH | SPI_3WIRE | SPI_LSB_FIRST;
206+
207+
master->bus_num = pdev->id;
208+
master->num_chipselect = 1;
209+
master->setup = spi_lp8841_rtc_setup;
210+
master->set_cs = spi_lp8841_rtc_set_cs;
211+
master->transfer_one = spi_lp8841_rtc_transfer_one;
212+
master->bits_per_word_mask = SPI_BPW_MASK(8);
213+
#ifdef CONFIG_OF
214+
master->dev.of_node = pdev->dev.of_node;
215+
#endif
216+
217+
data = spi_master_get_devdata(master);
218+
219+
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
220+
data->iomem = devm_ioremap_resource(&pdev->dev, iomem);
221+
ret = PTR_ERR_OR_ZERO(data->iomem);
222+
if (ret) {
223+
dev_err(&pdev->dev, "failed to get IO address\n");
224+
goto err_put_master;
225+
}
226+
227+
/* register with the SPI framework */
228+
ret = devm_spi_register_master(&pdev->dev, master);
229+
if (ret) {
230+
dev_err(&pdev->dev, "cannot register spi master\n");
231+
goto err_put_master;
232+
}
233+
234+
return ret;
235+
236+
237+
err_put_master:
238+
spi_master_put(master);
239+
240+
return ret;
241+
}
242+
243+
MODULE_ALIAS("platform:" DRIVER_NAME);
244+
245+
static struct platform_driver spi_lp8841_rtc_driver = {
246+
.driver = {
247+
.name = DRIVER_NAME,
248+
.of_match_table = of_match_ptr(spi_lp8841_rtc_dt_ids),
249+
},
250+
.probe = spi_lp8841_rtc_probe,
251+
};
252+
module_platform_driver(spi_lp8841_rtc_driver);
253+
254+
MODULE_DESCRIPTION("SPI master driver for ICP DAS LP-8841 RTC");
255+
MODULE_AUTHOR("Sergei Ianovich");
256+
MODULE_LICENSE("GPL");

drivers/spi/spi-pl022.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,6 @@ struct vendor_data {
346346
* @clk: outgoing clock "SPICLK" for the SPI bus
347347
* @master: SPI framework hookup
348348
* @master_info: controller-specific data from machine setup
349-
* @kworker: thread struct for message pump
350-
* @kworker_task: pointer to task for message pump kworker thread
351-
* @pump_messages: work struct for scheduling work to the message pump
352-
* @queue_lock: spinlock to syncronise access to message queue
353-
* @queue: message queue
354-
* @busy: message pump is busy
355-
* @running: message pump is running
356349
* @pump_transfers: Tasklet used in Interrupt Transfer mode
357350
* @cur_msg: Pointer to current spi_message being processed
358351
* @cur_transfer: Pointer to current spi_transfer

drivers/spi/spi-pxa2xx-dma.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
254254
if (status & SSSR_ROR) {
255255
dev_err(&drv_data->pdev->dev, "FIFO overrun\n");
256256

257-
dmaengine_terminate_all(drv_data->rx_chan);
258-
dmaengine_terminate_all(drv_data->tx_chan);
257+
dmaengine_terminate_async(drv_data->rx_chan);
258+
dmaengine_terminate_async(drv_data->tx_chan);
259259

260260
pxa2xx_spi_dma_transfer_complete(drv_data, true);
261261
return IRQ_HANDLED;
@@ -331,13 +331,13 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
331331
void pxa2xx_spi_dma_release(struct driver_data *drv_data)
332332
{
333333
if (drv_data->rx_chan) {
334-
dmaengine_terminate_all(drv_data->rx_chan);
334+
dmaengine_terminate_sync(drv_data->rx_chan);
335335
dma_release_channel(drv_data->rx_chan);
336336
sg_free_table(&drv_data->rx_sgt);
337337
drv_data->rx_chan = NULL;
338338
}
339339
if (drv_data->tx_chan) {
340-
dmaengine_terminate_all(drv_data->tx_chan);
340+
dmaengine_terminate_sync(drv_data->tx_chan);
341341
dma_release_channel(drv_data->tx_chan);
342342
sg_free_table(&drv_data->tx_sgt);
343343
drv_data->tx_chan = NULL;

0 commit comments

Comments
 (0)