Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Apr 14-17, 2025
Register
Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright (c) 2018 Nuvoton Technology corporation.
  3
  4#include <linux/kernel.h>
  5#include <linux/bitfield.h>
  6#include <linux/bitops.h>
  7#include <linux/clk.h>
  8#include <linux/interrupt.h>
  9#include <linux/io.h>
 10#include <linux/module.h>
 11#include <linux/platform_device.h>
 12#include <linux/spi/spi.h>
 13#include <linux/reset.h>
 
 14
 15#include <asm/unaligned.h>
 16
 17#include <linux/regmap.h>
 18#include <linux/mfd/syscon.h>
 19
 20struct npcm_pspi {
 21	struct completion xfer_done;
 22	struct reset_control *reset;
 23	struct spi_master *master;
 24	unsigned int tx_bytes;
 25	unsigned int rx_bytes;
 26	void __iomem *base;
 27	bool is_save_param;
 28	u8 bits_per_word;
 29	const u8 *tx_buf;
 30	struct clk *clk;
 31	u32 speed_hz;
 32	u8 *rx_buf;
 33	u16 mode;
 34	u32 id;
 35};
 36
 37#define DRIVER_NAME "npcm-pspi"
 38
 39#define NPCM_PSPI_DATA		0x00
 40#define NPCM_PSPI_CTL1		0x02
 41#define NPCM_PSPI_STAT		0x04
 42
 43/* definitions for control and status register */
 44#define NPCM_PSPI_CTL1_SPIEN	BIT(0)
 45#define NPCM_PSPI_CTL1_MOD	BIT(2)
 46#define NPCM_PSPI_CTL1_EIR	BIT(5)
 47#define NPCM_PSPI_CTL1_EIW	BIT(6)
 48#define NPCM_PSPI_CTL1_SCM	BIT(7)
 49#define NPCM_PSPI_CTL1_SCIDL	BIT(8)
 50#define NPCM_PSPI_CTL1_SCDV6_0	GENMASK(15, 9)
 51
 52#define NPCM_PSPI_STAT_BSY	BIT(0)
 53#define NPCM_PSPI_STAT_RBF	BIT(1)
 54
 55/* general definitions */
 56#define NPCM_PSPI_TIMEOUT_MS		2000
 57#define NPCM_PSPI_MAX_CLK_DIVIDER	256
 58#define NPCM_PSPI_MIN_CLK_DIVIDER	4
 59#define NPCM_PSPI_DEFAULT_CLK		25000000
 60
 
 
 
 
 
 
 61static inline unsigned int bytes_per_word(unsigned int bits)
 62{
 63	return bits <= 8 ? 1 : 2;
 64}
 65
 66static inline void npcm_pspi_irq_enable(struct npcm_pspi *priv, u16 mask)
 67{
 68	u16 val;
 69
 70	val = ioread16(priv->base + NPCM_PSPI_CTL1);
 71	val |= mask;
 72	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
 73}
 74
 75static inline void npcm_pspi_irq_disable(struct npcm_pspi *priv, u16 mask)
 76{
 77	u16 val;
 78
 79	val = ioread16(priv->base + NPCM_PSPI_CTL1);
 80	val &= ~mask;
 81	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
 82}
 83
 84static inline void npcm_pspi_enable(struct npcm_pspi *priv)
 85{
 86	u16 val;
 87
 88	val = ioread16(priv->base + NPCM_PSPI_CTL1);
 89	val |= NPCM_PSPI_CTL1_SPIEN;
 90	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
 91}
 92
 93static inline void npcm_pspi_disable(struct npcm_pspi *priv)
 94{
 95	u16 val;
 96
 97	val = ioread16(priv->base + NPCM_PSPI_CTL1);
 98	val &= ~NPCM_PSPI_CTL1_SPIEN;
 99	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
100}
101
102static void npcm_pspi_set_mode(struct spi_device *spi)
103{
104	struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
105	u16 regtemp;
106	u16 mode_val;
107
108	switch (spi->mode & SPI_MODE_X_MASK) {
109	case SPI_MODE_0:
110		mode_val = 0;
111		break;
112	case SPI_MODE_1:
113		mode_val = NPCM_PSPI_CTL1_SCIDL;
114		break;
115	case SPI_MODE_2:
116		mode_val = NPCM_PSPI_CTL1_SCM;
117		break;
118	case SPI_MODE_3:
119		mode_val = NPCM_PSPI_CTL1_SCIDL | NPCM_PSPI_CTL1_SCM;
120		break;
121	}
122
123	regtemp = ioread16(priv->base + NPCM_PSPI_CTL1);
124	regtemp &= ~(NPCM_PSPI_CTL1_SCM | NPCM_PSPI_CTL1_SCIDL);
125	iowrite16(regtemp | mode_val, priv->base + NPCM_PSPI_CTL1);
126}
127
128static void npcm_pspi_set_transfer_size(struct npcm_pspi *priv, int size)
129{
130	u16 regtemp;
131
132	regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
133
134	switch (size) {
135	case 8:
136		regtemp &= ~NPCM_PSPI_CTL1_MOD;
137		break;
138	case 16:
139		regtemp |= NPCM_PSPI_CTL1_MOD;
140		break;
141	}
142
143	iowrite16(regtemp, NPCM_PSPI_CTL1 + priv->base);
144}
145
146static void npcm_pspi_set_baudrate(struct npcm_pspi *priv, unsigned int speed)
147{
148	u32 ckdiv;
149	u16 regtemp;
150
151	/* the supported rates are numbers from 4 to 256. */
152	ckdiv = DIV_ROUND_CLOSEST(clk_get_rate(priv->clk), (2 * speed)) - 1;
153
154	regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
155	regtemp &= ~NPCM_PSPI_CTL1_SCDV6_0;
156	iowrite16(regtemp | (ckdiv << 9), NPCM_PSPI_CTL1 + priv->base);
157}
158
159static void npcm_pspi_setup_transfer(struct spi_device *spi,
160				     struct spi_transfer *t)
161{
162	struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
163
164	priv->tx_buf = t->tx_buf;
165	priv->rx_buf = t->rx_buf;
166	priv->tx_bytes = t->len;
167	priv->rx_bytes = t->len;
168
169	if (!priv->is_save_param || priv->mode != spi->mode) {
170		npcm_pspi_set_mode(spi);
171		priv->mode = spi->mode;
172	}
173
174	/*
175	 * If transfer is even length, and 8 bits per word transfer,
176	 * then implement 16 bits-per-word transfer.
177	 */
178	if (priv->bits_per_word == 8 && !(t->len & 0x1))
179		t->bits_per_word = 16;
180
181	if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) {
182		npcm_pspi_set_transfer_size(priv, t->bits_per_word);
183		priv->bits_per_word = t->bits_per_word;
184	}
185
186	if (!priv->is_save_param || priv->speed_hz != t->speed_hz) {
187		npcm_pspi_set_baudrate(priv, t->speed_hz);
188		priv->speed_hz = t->speed_hz;
189	}
190
191	if (!priv->is_save_param)
192		priv->is_save_param = true;
193}
194
195static void npcm_pspi_send(struct npcm_pspi *priv)
196{
197	int wsize;
198	u16 val;
199
200	wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
201	priv->tx_bytes -= wsize;
202
203	if (!priv->tx_buf)
204		return;
205
206	switch (wsize) {
207	case 1:
208		val = *priv->tx_buf++;
209		iowrite8(val, NPCM_PSPI_DATA + priv->base);
210		break;
211	case 2:
212		val = *priv->tx_buf++;
213		val = *priv->tx_buf++ | (val << 8);
214		iowrite16(val, NPCM_PSPI_DATA + priv->base);
215		break;
216	default:
217		WARN_ON_ONCE(1);
218		return;
219	}
 
 
220}
221
222static void npcm_pspi_recv(struct npcm_pspi *priv)
223{
224	int rsize;
225	u16 val;
226
227	rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
228	priv->rx_bytes -= rsize;
229
230	if (!priv->rx_buf)
231		return;
232
233	switch (rsize) {
234	case 1:
235		*priv->rx_buf++ = ioread8(priv->base + NPCM_PSPI_DATA);
236		break;
237	case 2:
238		val = ioread16(priv->base + NPCM_PSPI_DATA);
239		*priv->rx_buf++ = (val >> 8);
240		*priv->rx_buf++ = val & 0xff;
241		break;
242	default:
243		WARN_ON_ONCE(1);
244		return;
245	}
 
 
 
246}
247
248static int npcm_pspi_transfer_one(struct spi_master *master,
249				  struct spi_device *spi,
250				  struct spi_transfer *t)
251{
252	struct npcm_pspi *priv = spi_master_get_devdata(master);
253	int status;
254
255	npcm_pspi_setup_transfer(spi, t);
256	reinit_completion(&priv->xfer_done);
257	npcm_pspi_enable(priv);
258	status = wait_for_completion_timeout(&priv->xfer_done,
259					     msecs_to_jiffies
260					     (NPCM_PSPI_TIMEOUT_MS));
261	if (status == 0) {
262		npcm_pspi_disable(priv);
263		return -ETIMEDOUT;
264	}
265
266	return 0;
267}
268
269static int npcm_pspi_prepare_transfer_hardware(struct spi_master *master)
270{
271	struct npcm_pspi *priv = spi_master_get_devdata(master);
272
273	npcm_pspi_irq_enable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
274
275	return 0;
276}
277
278static int npcm_pspi_unprepare_transfer_hardware(struct spi_master *master)
279{
280	struct npcm_pspi *priv = spi_master_get_devdata(master);
281
282	npcm_pspi_irq_disable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
283
284	return 0;
285}
286
287static void npcm_pspi_reset_hw(struct npcm_pspi *priv)
288{
289	reset_control_assert(priv->reset);
290	udelay(5);
291	reset_control_deassert(priv->reset);
292}
293
294static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
295{
296	struct npcm_pspi *priv = dev_id;
 
297	u8 stat;
298
299	stat = ioread8(priv->base + NPCM_PSPI_STAT);
300
301	if (!priv->tx_buf && !priv->rx_buf)
302		return IRQ_NONE;
303
304	if (priv->tx_buf) {
305		if (stat & NPCM_PSPI_STAT_RBF) {
306			ioread8(NPCM_PSPI_DATA + priv->base);
307			if (priv->tx_bytes == 0) {
308				npcm_pspi_disable(priv);
309				complete(&priv->xfer_done);
310				return IRQ_HANDLED;
311			}
312		}
313
314		if ((stat & NPCM_PSPI_STAT_BSY) == 0)
315			if (priv->tx_bytes)
316				npcm_pspi_send(priv);
317	}
318
319	if (priv->rx_buf) {
320		if (stat & NPCM_PSPI_STAT_RBF) {
321			if (!priv->rx_bytes)
322				return IRQ_NONE;
323
324			npcm_pspi_recv(priv);
325
326			if (!priv->rx_bytes) {
327				npcm_pspi_disable(priv);
328				complete(&priv->xfer_done);
329				return IRQ_HANDLED;
330			}
331		}
332
333		if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
334			iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
335	}
336
337	return IRQ_HANDLED;
338}
339
340static int npcm_pspi_probe(struct platform_device *pdev)
341{
342	struct npcm_pspi *priv;
343	struct spi_master *master;
344	unsigned long clk_hz;
 
 
 
345	int irq;
346	int ret;
347
 
 
 
 
 
 
 
 
348	master = spi_alloc_master(&pdev->dev, sizeof(*priv));
349	if (!master)
350		return -ENOMEM;
351
352	platform_set_drvdata(pdev, master);
353
354	priv = spi_master_get_devdata(master);
355	priv->master = master;
356	priv->is_save_param = false;
 
357
358	priv->base = devm_platform_ioremap_resource(pdev, 0);
359	if (IS_ERR(priv->base)) {
360		ret = PTR_ERR(priv->base);
361		goto out_master_put;
362	}
363
364	priv->clk = devm_clk_get(&pdev->dev, NULL);
365	if (IS_ERR(priv->clk)) {
366		dev_err(&pdev->dev, "failed to get clock\n");
367		ret = PTR_ERR(priv->clk);
368		goto out_master_put;
369	}
370
371	ret = clk_prepare_enable(priv->clk);
372	if (ret)
373		goto out_master_put;
374
375	irq = platform_get_irq(pdev, 0);
376	if (irq < 0) {
377		ret = irq;
378		goto out_disable_clk;
379	}
380
381	priv->reset = devm_reset_control_get(&pdev->dev, NULL);
382	if (IS_ERR(priv->reset)) {
383		ret = PTR_ERR(priv->reset);
384		goto out_disable_clk;
 
385	}
386
387	/* reset SPI-HW block */
388	npcm_pspi_reset_hw(priv);
389
390	ret = devm_request_irq(&pdev->dev, irq, npcm_pspi_handler, 0,
391			       "npcm-pspi", priv);
392	if (ret) {
393		dev_err(&pdev->dev, "failed to request IRQ\n");
394		goto out_disable_clk;
395	}
396
397	init_completion(&priv->xfer_done);
398
399	clk_hz = clk_get_rate(priv->clk);
400
401	master->max_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MIN_CLK_DIVIDER);
402	master->min_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MAX_CLK_DIVIDER);
403	master->mode_bits = SPI_CPHA | SPI_CPOL;
404	master->dev.of_node = pdev->dev.of_node;
405	master->bus_num = -1;
406	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
407	master->transfer_one = npcm_pspi_transfer_one;
408	master->prepare_transfer_hardware =
409		npcm_pspi_prepare_transfer_hardware;
410	master->unprepare_transfer_hardware =
411		npcm_pspi_unprepare_transfer_hardware;
412	master->use_gpio_descriptors = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
414	/* set to default clock rate */
415	npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK);
416
417	ret = devm_spi_register_master(&pdev->dev, master);
418	if (ret)
419		goto out_disable_clk;
420
421	pr_info("NPCM Peripheral SPI %d probed\n", master->bus_num);
422
423	return 0;
424
425out_disable_clk:
426	clk_disable_unprepare(priv->clk);
427
428out_master_put:
429	spi_master_put(master);
430	return ret;
431}
432
433static int npcm_pspi_remove(struct platform_device *pdev)
434{
435	struct spi_master *master = platform_get_drvdata(pdev);
436	struct npcm_pspi *priv = spi_master_get_devdata(master);
437
438	npcm_pspi_reset_hw(priv);
439	clk_disable_unprepare(priv->clk);
440
441	return 0;
442}
443
444static const struct of_device_id npcm_pspi_match[] = {
445	{ .compatible = "nuvoton,npcm750-pspi", .data = NULL },
446	{ .compatible = "nuvoton,npcm845-pspi", .data = NULL },
447	{}
448};
449MODULE_DEVICE_TABLE(of, npcm_pspi_match);
450
451static struct platform_driver npcm_pspi_driver = {
452	.driver		= {
453		.name		= DRIVER_NAME,
454		.of_match_table	= npcm_pspi_match,
455	},
456	.probe		= npcm_pspi_probe,
457	.remove		= npcm_pspi_remove,
458};
459module_platform_driver(npcm_pspi_driver);
460
461MODULE_DESCRIPTION("NPCM peripheral SPI Controller driver");
462MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
463MODULE_LICENSE("GPL v2");
464
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright (c) 2018 Nuvoton Technology corporation.
  3
  4#include <linux/kernel.h>
  5#include <linux/bitfield.h>
  6#include <linux/bitops.h>
  7#include <linux/clk.h>
  8#include <linux/interrupt.h>
  9#include <linux/io.h>
 10#include <linux/module.h>
 11#include <linux/platform_device.h>
 12#include <linux/spi/spi.h>
 13#include <linux/gpio.h>
 14#include <linux/of_gpio.h>
 15
 16#include <asm/unaligned.h>
 17
 18#include <linux/regmap.h>
 19#include <linux/mfd/syscon.h>
 20
 21struct npcm_pspi {
 22	struct completion xfer_done;
 23	struct regmap *rst_regmap;
 24	struct spi_master *master;
 25	unsigned int tx_bytes;
 26	unsigned int rx_bytes;
 27	void __iomem *base;
 28	bool is_save_param;
 29	u8 bits_per_word;
 30	const u8 *tx_buf;
 31	struct clk *clk;
 32	u32 speed_hz;
 33	u8 *rx_buf;
 34	u16 mode;
 35	u32 id;
 36};
 37
 38#define DRIVER_NAME "npcm-pspi"
 39
 40#define NPCM_PSPI_DATA		0x00
 41#define NPCM_PSPI_CTL1		0x02
 42#define NPCM_PSPI_STAT		0x04
 43
 44/* definitions for control and status register */
 45#define NPCM_PSPI_CTL1_SPIEN	BIT(0)
 46#define NPCM_PSPI_CTL1_MOD	BIT(2)
 47#define NPCM_PSPI_CTL1_EIR	BIT(5)
 48#define NPCM_PSPI_CTL1_EIW	BIT(6)
 49#define NPCM_PSPI_CTL1_SCM	BIT(7)
 50#define NPCM_PSPI_CTL1_SCIDL	BIT(8)
 51#define NPCM_PSPI_CTL1_SCDV6_0	GENMASK(15, 9)
 52
 53#define NPCM_PSPI_STAT_BSY	BIT(0)
 54#define NPCM_PSPI_STAT_RBF	BIT(1)
 55
 56/* general definitions */
 57#define NPCM_PSPI_TIMEOUT_MS		2000
 58#define NPCM_PSPI_MAX_CLK_DIVIDER	256
 59#define NPCM_PSPI_MIN_CLK_DIVIDER	4
 60#define NPCM_PSPI_DEFAULT_CLK		25000000
 61
 62/* reset register */
 63#define NPCM7XX_IPSRST2_OFFSET	0x24
 64
 65#define NPCM7XX_PSPI1_RESET	BIT(22)
 66#define NPCM7XX_PSPI2_RESET	BIT(23)
 67
 68static inline unsigned int bytes_per_word(unsigned int bits)
 69{
 70	return bits <= 8 ? 1 : 2;
 71}
 72
 73static inline void npcm_pspi_irq_enable(struct npcm_pspi *priv, u16 mask)
 74{
 75	u16 val;
 76
 77	val = ioread16(priv->base + NPCM_PSPI_CTL1);
 78	val |= mask;
 79	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
 80}
 81
 82static inline void npcm_pspi_irq_disable(struct npcm_pspi *priv, u16 mask)
 83{
 84	u16 val;
 85
 86	val = ioread16(priv->base + NPCM_PSPI_CTL1);
 87	val &= ~mask;
 88	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
 89}
 90
 91static inline void npcm_pspi_enable(struct npcm_pspi *priv)
 92{
 93	u16 val;
 94
 95	val = ioread16(priv->base + NPCM_PSPI_CTL1);
 96	val |= NPCM_PSPI_CTL1_SPIEN;
 97	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
 98}
 99
100static inline void npcm_pspi_disable(struct npcm_pspi *priv)
101{
102	u16 val;
103
104	val = ioread16(priv->base + NPCM_PSPI_CTL1);
105	val &= ~NPCM_PSPI_CTL1_SPIEN;
106	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
107}
108
109static void npcm_pspi_set_mode(struct spi_device *spi)
110{
111	struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
112	u16 regtemp;
113	u16 mode_val;
114
115	switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
116	case SPI_MODE_0:
117		mode_val = 0;
118		break;
119	case SPI_MODE_1:
120		mode_val = NPCM_PSPI_CTL1_SCIDL;
121		break;
122	case SPI_MODE_2:
123		mode_val = NPCM_PSPI_CTL1_SCM;
124		break;
125	case SPI_MODE_3:
126		mode_val = NPCM_PSPI_CTL1_SCIDL | NPCM_PSPI_CTL1_SCM;
127		break;
128	}
129
130	regtemp = ioread16(priv->base + NPCM_PSPI_CTL1);
131	regtemp &= ~(NPCM_PSPI_CTL1_SCM | NPCM_PSPI_CTL1_SCIDL);
132	iowrite16(regtemp | mode_val, priv->base + NPCM_PSPI_CTL1);
133}
134
135static void npcm_pspi_set_transfer_size(struct npcm_pspi *priv, int size)
136{
137	u16 regtemp;
138
139	regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
140
141	switch (size) {
142	case 8:
143		regtemp &= ~NPCM_PSPI_CTL1_MOD;
144		break;
145	case 16:
146		regtemp |= NPCM_PSPI_CTL1_MOD;
147		break;
148	}
149
150	iowrite16(regtemp, NPCM_PSPI_CTL1 + priv->base);
151}
152
153static void npcm_pspi_set_baudrate(struct npcm_pspi *priv, unsigned int speed)
154{
155	u32 ckdiv;
156	u16 regtemp;
157
158	/* the supported rates are numbers from 4 to 256. */
159	ckdiv = DIV_ROUND_CLOSEST(clk_get_rate(priv->clk), (2 * speed)) - 1;
160
161	regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
162	regtemp &= ~NPCM_PSPI_CTL1_SCDV6_0;
163	iowrite16(regtemp | (ckdiv << 9), NPCM_PSPI_CTL1 + priv->base);
164}
165
166static void npcm_pspi_setup_transfer(struct spi_device *spi,
167				     struct spi_transfer *t)
168{
169	struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
170
171	priv->tx_buf = t->tx_buf;
172	priv->rx_buf = t->rx_buf;
173	priv->tx_bytes = t->len;
174	priv->rx_bytes = t->len;
175
176	if (!priv->is_save_param || priv->mode != spi->mode) {
177		npcm_pspi_set_mode(spi);
178		priv->mode = spi->mode;
179	}
180
 
 
 
 
 
 
 
181	if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) {
182		npcm_pspi_set_transfer_size(priv, t->bits_per_word);
183		priv->bits_per_word = t->bits_per_word;
184	}
185
186	if (!priv->is_save_param || priv->speed_hz != t->speed_hz) {
187		npcm_pspi_set_baudrate(priv, t->speed_hz);
188		priv->speed_hz = t->speed_hz;
189	}
190
191	if (!priv->is_save_param)
192		priv->is_save_param = true;
193}
194
195static void npcm_pspi_send(struct npcm_pspi *priv)
196{
197	int wsize;
 
198
199	wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
200	priv->tx_bytes -= wsize;
201
202	if (!priv->tx_buf)
203		return;
204
205	switch (wsize) {
206	case 1:
207		iowrite8(*priv->tx_buf, NPCM_PSPI_DATA + priv->base);
 
208		break;
209	case 2:
210		iowrite16(*priv->tx_buf, NPCM_PSPI_DATA + priv->base);
 
 
211		break;
212	default:
213		WARN_ON_ONCE(1);
214		return;
215	}
216
217	priv->tx_buf += wsize;
218}
219
220static void npcm_pspi_recv(struct npcm_pspi *priv)
221{
222	int rsize;
223	u16 val;
224
225	rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
226	priv->rx_bytes -= rsize;
227
228	if (!priv->rx_buf)
229		return;
230
231	switch (rsize) {
232	case 1:
233		val = ioread8(priv->base + NPCM_PSPI_DATA);
234		break;
235	case 2:
236		val = ioread16(priv->base + NPCM_PSPI_DATA);
 
 
237		break;
238	default:
239		WARN_ON_ONCE(1);
240		return;
241	}
242
243	*priv->rx_buf = val;
244	priv->rx_buf += rsize;
245}
246
247static int npcm_pspi_transfer_one(struct spi_master *master,
248				  struct spi_device *spi,
249				  struct spi_transfer *t)
250{
251	struct npcm_pspi *priv = spi_master_get_devdata(master);
252	int status;
253
254	npcm_pspi_setup_transfer(spi, t);
255	reinit_completion(&priv->xfer_done);
256	npcm_pspi_enable(priv);
257	status = wait_for_completion_timeout(&priv->xfer_done,
258					     msecs_to_jiffies
259					     (NPCM_PSPI_TIMEOUT_MS));
260	if (status == 0) {
261		npcm_pspi_disable(priv);
262		return -ETIMEDOUT;
263	}
264
265	return 0;
266}
267
268static int npcm_pspi_prepare_transfer_hardware(struct spi_master *master)
269{
270	struct npcm_pspi *priv = spi_master_get_devdata(master);
271
272	npcm_pspi_irq_enable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
273
274	return 0;
275}
276
277static int npcm_pspi_unprepare_transfer_hardware(struct spi_master *master)
278{
279	struct npcm_pspi *priv = spi_master_get_devdata(master);
280
281	npcm_pspi_irq_disable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
282
283	return 0;
284}
285
286static void npcm_pspi_reset_hw(struct npcm_pspi *priv)
287{
288	regmap_write(priv->rst_regmap, NPCM7XX_IPSRST2_OFFSET,
289		     NPCM7XX_PSPI1_RESET << priv->id);
290	regmap_write(priv->rst_regmap, NPCM7XX_IPSRST2_OFFSET, 0x0);
291}
292
293static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
294{
295	struct npcm_pspi *priv = dev_id;
296	u16 val;
297	u8 stat;
298
299	stat = ioread8(priv->base + NPCM_PSPI_STAT);
300
301	if (!priv->tx_buf && !priv->rx_buf)
302		return IRQ_NONE;
303
304	if (priv->tx_buf) {
305		if (stat & NPCM_PSPI_STAT_RBF) {
306			val = ioread8(NPCM_PSPI_DATA + priv->base);
307			if (priv->tx_bytes == 0) {
308				npcm_pspi_disable(priv);
309				complete(&priv->xfer_done);
310				return IRQ_HANDLED;
311			}
312		}
313
314		if ((stat & NPCM_PSPI_STAT_BSY) == 0)
315			if (priv->tx_bytes)
316				npcm_pspi_send(priv);
317	}
318
319	if (priv->rx_buf) {
320		if (stat & NPCM_PSPI_STAT_RBF) {
321			if (!priv->rx_bytes)
322				return IRQ_NONE;
323
324			npcm_pspi_recv(priv);
325
326			if (!priv->rx_bytes) {
327				npcm_pspi_disable(priv);
328				complete(&priv->xfer_done);
329				return IRQ_HANDLED;
330			}
331		}
332
333		if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
334			iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
335	}
336
337	return IRQ_HANDLED;
338}
339
340static int npcm_pspi_probe(struct platform_device *pdev)
341{
342	struct npcm_pspi *priv;
343	struct spi_master *master;
344	unsigned long clk_hz;
345	struct device_node *np = pdev->dev.of_node;
346	int num_cs, i;
347	int csgpio;
348	int irq;
349	int ret;
350
351	num_cs = of_gpio_named_count(np, "cs-gpios");
352	if (num_cs < 0)
353		return num_cs;
354
355	pdev->id = of_alias_get_id(np, "spi");
356	if (pdev->id < 0)
357		pdev->id = 0;
358
359	master = spi_alloc_master(&pdev->dev, sizeof(*priv));
360	if (!master)
361		return -ENOMEM;
362
363	platform_set_drvdata(pdev, master);
364
365	priv = spi_master_get_devdata(master);
366	priv->master = master;
367	priv->is_save_param = false;
368	priv->id = pdev->id;
369
370	priv->base = devm_platform_ioremap_resource(pdev, 0);
371	if (IS_ERR(priv->base)) {
372		ret = PTR_ERR(priv->base);
373		goto out_master_put;
374	}
375
376	priv->clk = devm_clk_get(&pdev->dev, NULL);
377	if (IS_ERR(priv->clk)) {
378		dev_err(&pdev->dev, "failed to get clock\n");
379		ret = PTR_ERR(priv->clk);
380		goto out_master_put;
381	}
382
383	ret = clk_prepare_enable(priv->clk);
384	if (ret)
385		goto out_master_put;
386
387	irq = platform_get_irq(pdev, 0);
388	if (irq < 0) {
389		ret = irq;
390		goto out_disable_clk;
391	}
392
393	priv->rst_regmap =
394		syscon_regmap_lookup_by_compatible("nuvoton,npcm750-rst");
395	if (IS_ERR(priv->rst_regmap)) {
396		dev_err(&pdev->dev, "failed to find nuvoton,npcm750-rst\n");
397		return PTR_ERR(priv->rst_regmap);
398	}
399
400	/* reset SPI-HW block */
401	npcm_pspi_reset_hw(priv);
402
403	ret = devm_request_irq(&pdev->dev, irq, npcm_pspi_handler, 0,
404			       "npcm-pspi", priv);
405	if (ret) {
406		dev_err(&pdev->dev, "failed to request IRQ\n");
407		goto out_disable_clk;
408	}
409
410	init_completion(&priv->xfer_done);
411
412	clk_hz = clk_get_rate(priv->clk);
413
414	master->max_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MIN_CLK_DIVIDER);
415	master->min_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MAX_CLK_DIVIDER);
416	master->mode_bits = SPI_CPHA | SPI_CPOL;
417	master->dev.of_node = pdev->dev.of_node;
418	master->bus_num = pdev->id;
419	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
420	master->transfer_one = npcm_pspi_transfer_one;
421	master->prepare_transfer_hardware =
422		npcm_pspi_prepare_transfer_hardware;
423	master->unprepare_transfer_hardware =
424		npcm_pspi_unprepare_transfer_hardware;
425	master->num_chipselect = num_cs;
426
427	for (i = 0; i < num_cs; i++) {
428		csgpio = of_get_named_gpio(np, "cs-gpios", i);
429		if (csgpio < 0) {
430			dev_err(&pdev->dev, "failed to get csgpio#%u\n", i);
431			goto out_disable_clk;
432		}
433		dev_dbg(&pdev->dev, "csgpio#%u = %d\n", i, csgpio);
434		ret = devm_gpio_request_one(&pdev->dev, csgpio,
435					    GPIOF_OUT_INIT_HIGH, DRIVER_NAME);
436		if (ret < 0) {
437			dev_err(&pdev->dev,
438				"failed to configure csgpio#%u %d\n"
439				, i, csgpio);
440			goto out_disable_clk;
441		}
442	}
443
444	/* set to default clock rate */
445	npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK);
446
447	ret = devm_spi_register_master(&pdev->dev, master);
448	if (ret)
449		goto out_disable_clk;
450
451	pr_info("NPCM Peripheral SPI %d probed\n", pdev->id);
452
453	return 0;
454
455out_disable_clk:
456	clk_disable_unprepare(priv->clk);
457
458out_master_put:
459	spi_master_put(master);
460	return ret;
461}
462
463static int npcm_pspi_remove(struct platform_device *pdev)
464{
465	struct spi_master *master = platform_get_drvdata(pdev);
466	struct npcm_pspi *priv = spi_master_get_devdata(master);
467
468	npcm_pspi_reset_hw(priv);
469	clk_disable_unprepare(priv->clk);
470
471	return 0;
472}
473
474static const struct of_device_id npcm_pspi_match[] = {
475	{ .compatible = "nuvoton,npcm750-pspi", .data = NULL },
 
476	{}
477};
478MODULE_DEVICE_TABLE(of, npcm_pspi_match);
479
480static struct platform_driver npcm_pspi_driver = {
481	.driver		= {
482		.name		= DRIVER_NAME,
483		.of_match_table	= npcm_pspi_match,
484	},
485	.probe		= npcm_pspi_probe,
486	.remove		= npcm_pspi_remove,
487};
488module_platform_driver(npcm_pspi_driver);
489
490MODULE_DESCRIPTION("NPCM peripheral SPI Controller driver");
491MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
492MODULE_LICENSE("GPL v2");
493