spi-s3c24xx.c 14.8 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-only
Grant Likely's avatar
Grant Likely committed
2
/*
3
 * Copyright (c) 2006 Ben Dooks
4
 * Copyright 2006-2009 Simtec Electronics
5
6
7
8
9
10
11
12
13
14
 *	Ben Dooks <ben@simtec.co.uk>
*/

#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
15
#include <linux/gpio.h>
Ben Dooks's avatar
Ben Dooks committed
16
#include <linux/io.h>
17
#include <linux/slab.h>
18
19
20

#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
21
#include <linux/spi/s3c24xx.h>
22
#include <linux/module.h>
23

24
#include <plat/regs-spi.h>
25

26
27
#include <asm/fiq.h>

Grant Likely's avatar
Grant Likely committed
28
#include "spi-s3c24xx-fiq.h"
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
 * s3c24xx_spi_devstate - per device data
 * @hz: Last frequency calculated for @sppre field.
 * @mode: Last mode setting for the @spcon field.
 * @spcon: Value to write to the SPCON register.
 * @sppre: Value to write to the SPPRE register.
 */
struct s3c24xx_spi_devstate {
	unsigned int	hz;
	unsigned int	mode;
	u8		spcon;
	u8		sppre;
};

44
45
46
47
48
49
50
enum spi_fiq_mode {
	FIQ_MODE_NONE	= 0,
	FIQ_MODE_TX	= 1,
	FIQ_MODE_RX	= 2,
	FIQ_MODE_TXRX	= 3,
};

51
52
53
54
55
56
57
58
59
60
struct s3c24xx_spi {
	/* bitbang has to be first */
	struct spi_bitbang	 bitbang;
	struct completion	 done;

	void __iomem		*regs;
	int			 irq;
	int			 len;
	int			 count;

61
62
63
64
65
	struct fiq_handler	 fiq_handler;
	enum spi_fiq_mode	 fiq_mode;
	unsigned char		 fiq_inuse;
	unsigned char		 fiq_claimed;

66
	void			(*set_cs)(struct s3c2410_spi_info *spi,
67
68
					  int cs, int pol);

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
	/* data buffers */
	const unsigned char	*tx;
	unsigned char		*rx;

	struct clk		*clk;
	struct spi_master	*master;
	struct spi_device	*curdev;
	struct device		*dev;
	struct s3c2410_spi_info *pdata;
};

#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)
#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP)

static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev)
{
	return spi_master_get_devdata(sdev->master);
}

88
89
static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol)
{
90
	gpio_set_value(spi->pin_cs, pol);
91
92
}

93
94
static void s3c24xx_spi_chipsel(struct spi_device *spi, int value)
{
95
	struct s3c24xx_spi_devstate *cs = spi->controller_state;
96
97
	struct s3c24xx_spi *hw = to_hw(spi);
	unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
98
99

	/* change the chipselect state and the state of the spi engine clock */
100
101
102

	switch (value) {
	case BITBANG_CS_INACTIVE:
103
		hw->set_cs(hw->pdata, spi->chip_select, cspol^1);
104
		writeb(cs->spcon, hw->regs + S3C2410_SPCON);
105
106
107
		break;

	case BITBANG_CS_ACTIVE:
108
109
		writeb(cs->spcon | S3C2410_SPCON_ENSCK,
		       hw->regs + S3C2410_SPCON);
110
		hw->set_cs(hw->pdata, spi->chip_select, cspol);
111
112
113
114
		break;
	}
}

115
116
static int s3c24xx_spi_update_state(struct spi_device *spi,
				    struct spi_transfer *t)
117
118
{
	struct s3c24xx_spi *hw = to_hw(spi);
119
	struct s3c24xx_spi_devstate *cs = spi->controller_state;
120
121
	unsigned int hz;
	unsigned int div;
122
	unsigned long clk;
123
124
125

	hz  = t ? t->speed_hz : spi->max_speed_hz;

126
127
128
	if (!hz)
		hz = spi->max_speed_hz;

129
	if (spi->mode != cs->mode) {
130
		u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK;
131
132
133

		if (spi->mode & SPI_CPHA)
			spcon |= S3C2410_SPCON_CPHA_FMTB;
134

135
136
		if (spi->mode & SPI_CPOL)
			spcon |= S3C2410_SPCON_CPOL_HIGH;
137

138
139
140
		cs->mode = spi->mode;
		cs->spcon = spcon;
	}
141

142
143
144
	if (cs->hz != hz) {
		clk = clk_get_rate(hw->clk);
		div = DIV_ROUND_UP(clk, hz * 2) - 1;
145

146
147
		if (div > 255)
			div = 255;
148

149
150
151
152
153
		dev_dbg(&spi->dev, "pre-scaler=%d (wanted %d, got %ld)\n",
			div, hz, clk / (2 * (div + 1)));

		cs->hz = hz;
		cs->sppre = div;
154
155
156
157
158
	}

	return 0;
}

159
160
161
162
163
164
165
166
167
168
169
170
171
172
static int s3c24xx_spi_setupxfer(struct spi_device *spi,
				 struct spi_transfer *t)
{
	struct s3c24xx_spi_devstate *cs = spi->controller_state;
	struct s3c24xx_spi *hw = to_hw(spi);
	int ret;

	ret = s3c24xx_spi_update_state(spi, t);
	if (!ret)
		writeb(cs->sppre, hw->regs + S3C2410_SPPRE);

	return ret;
}

173
174
static int s3c24xx_spi_setup(struct spi_device *spi)
{
175
176
	struct s3c24xx_spi_devstate *cs = spi->controller_state;
	struct s3c24xx_spi *hw = to_hw(spi);
177
178
	int ret;

179
180
	/* allocate settings on the first call */
	if (!cs) {
181
182
183
		cs = devm_kzalloc(&spi->dev,
				  sizeof(struct s3c24xx_spi_devstate),
				  GFP_KERNEL);
184
		if (!cs)
185
186
187
188
189
190
191
192
193
194
			return -ENOMEM;

		cs->spcon = SPCON_DEFAULT;
		cs->hz = -1;
		spi->controller_state = cs;
	}

	/* initialise the state from the device */
	ret = s3c24xx_spi_update_state(spi, NULL);
	if (ret)
195
		return ret;
196

197
	mutex_lock(&hw->bitbang.lock);
198
199
200
	if (!hw->bitbang.busy) {
		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
		/* need to ndelay for 0.5 clocktick ? */
201
	}
202
	mutex_unlock(&hw->bitbang.lock);
203
204
205
206
207
208

	return 0;
}

static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count)
{
209
	return hw->tx ? hw->tx[count] : 0;
210
211
}

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#ifdef CONFIG_SPI_S3C24XX_FIQ
/* Support for FIQ based pseudo-DMA to improve the transfer speed.
 *
 * This code uses the assembly helper in spi_s3c24xx_spi.S which is
 * used by the FIQ core to move data between main memory and the peripheral
 * block. Since this is code running on the processor, there is no problem
 * with cache coherency of the buffers, so we can use any buffer we like.
 */

/**
 * struct spi_fiq_code - FIQ code and header
 * @length: The length of the code fragment, excluding this header.
 * @ack_offset: The offset from @data to the word to place the IRQ ACK bit at.
 * @data: The code itself to install as a FIQ handler.
 */
struct spi_fiq_code {
	u32	length;
	u32	ack_offset;
	u8	data[0];
};

extern struct spi_fiq_code s3c24xx_spi_fiq_txrx;
extern struct spi_fiq_code s3c24xx_spi_fiq_tx;
extern struct spi_fiq_code s3c24xx_spi_fiq_rx;

/**
 * ack_bit - turn IRQ into IRQ acknowledgement bit
 * @irq: The interrupt number
 *
 * Returns the bit to write to the interrupt acknowledge register.
 */
static inline u32 ack_bit(unsigned int irq)
{
	return 1 << (irq - IRQ_EINT0);
}

/**
 * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer
 * @hw: The hardware state.
 *
 * Claim the FIQ handler (only one can be active at any one time) and
 * then setup the correct transfer code for this transfer.
 *
255
 * This call updates all the necessary state information if successful,
256
257
258
 * so the caller does not need to do anything more than start the transfer
 * as normal, since the IRQ will have been re-routed to the FIQ handler.
*/
259
static void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw)
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
{
	struct pt_regs regs;
	enum spi_fiq_mode mode;
	struct spi_fiq_code *code;
	int ret;

	if (!hw->fiq_claimed) {
		/* try and claim fiq if we haven't got it, and if not
		 * then return and simply use another transfer method */

		ret = claim_fiq(&hw->fiq_handler);
		if (ret)
			return;
	}

	if (hw->tx && !hw->rx)
		mode = FIQ_MODE_TX;
	else if (hw->rx && !hw->tx)
		mode = FIQ_MODE_RX;
	else
		mode = FIQ_MODE_TXRX;

	regs.uregs[fiq_rspi] = (long)hw->regs;
	regs.uregs[fiq_rrx]  = (long)hw->rx;
	regs.uregs[fiq_rtx]  = (long)hw->tx + 1;
	regs.uregs[fiq_rcount] = hw->len - 1;
	regs.uregs[fiq_rirq] = (long)S3C24XX_VA_IRQ;

	set_fiq_regs(&regs);

	if (hw->fiq_mode != mode) {
		u32 *ack_ptr;

		hw->fiq_mode = mode;

		switch (mode) {
		case FIQ_MODE_TX:
			code = &s3c24xx_spi_fiq_tx;
			break;
		case FIQ_MODE_RX:
			code = &s3c24xx_spi_fiq_rx;
			break;
		case FIQ_MODE_TXRX:
			code = &s3c24xx_spi_fiq_txrx;
			break;
		default:
			code = NULL;
		}

		BUG_ON(!code);

		ack_ptr = (u32 *)&code->data[code->ack_offset];
		*ack_ptr = ack_bit(hw->irq);

		set_fiq_handler(&code->data, code->length);
	}

	s3c24xx_set_fiq(hw->irq, true);

	hw->fiq_mode = mode;
	hw->fiq_inuse = 1;
}

/**
 * s3c24xx_spi_fiqop - FIQ core code callback
 * @pw: Data registered with the handler
 * @release: Whether this is a release or a return.
 *
 * Called by the FIQ code when another module wants to use the FIQ, so
 * return whether we are currently using this or not and then update our
 * internal state.
 */
static int s3c24xx_spi_fiqop(void *pw, int release)
{
	struct s3c24xx_spi *hw = pw;
	int ret = 0;

	if (release) {
		if (hw->fiq_inuse)
			ret = -EBUSY;

		/* note, we do not need to unroute the FIQ, as the FIQ
		 * vector code de-routes it to signal the end of transfer */

		hw->fiq_mode = FIQ_MODE_NONE;
		hw->fiq_claimed = 0;
	} else {
		hw->fiq_claimed = 1;
	}

	return ret;
}

/**
 * s3c24xx_spi_initfiq - setup the information for the FIQ core
 * @hw: The hardware state.
 *
 * Setup the fiq_handler block to pass to the FIQ core.
 */
static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *hw)
{
	hw->fiq_handler.dev_id = hw;
	hw->fiq_handler.name = dev_name(hw->dev);
	hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop;
}

/**
 * s3c24xx_spi_usefiq - return if we should be using FIQ.
 * @hw: The hardware state.
 *
 * Return true if the platform data specifies whether this channel is
 * allowed to use the FIQ.
 */
static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *hw)
{
	return hw->pdata->use_fiq;
}

/**
 * s3c24xx_spi_usingfiq - return if channel is using FIQ
 * @spi: The hardware state.
 *
 * Return whether the channel is currently using the FIQ (separate from
 * whether the FIQ is claimed).
 */
static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *spi)
{
	return spi->fiq_inuse;
}
#else

static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *s) { }
static inline void s3c24xx_spi_tryfiq(struct s3c24xx_spi *s) { }
static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *s) { return false; }
static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *s) { return false; }

#endif /* CONFIG_SPI_S3C24XX_FIQ */

398
399
400
401
402
403
404
405
406
static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
{
	struct s3c24xx_spi *hw = to_hw(spi);

	hw->tx = t->tx_buf;
	hw->rx = t->rx_buf;
	hw->len = t->len;
	hw->count = 0;

407
408
	init_completion(&hw->done);

409
410
411
412
	hw->fiq_inuse = 0;
	if (s3c24xx_spi_usefiq(hw) && t->len >= 3)
		s3c24xx_spi_tryfiq(hw);

413
414
	/* send the first byte */
	writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
415

416
417
418
419
	wait_for_completion(&hw->done);
	return hw->count;
}

420
static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
{
	struct s3c24xx_spi *hw = dev;
	unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
	unsigned int count = hw->count;

	if (spsta & S3C2410_SPSTA_DCOL) {
		dev_dbg(hw->dev, "data-collision\n");
		complete(&hw->done);
		goto irq_done;
	}

	if (!(spsta & S3C2410_SPSTA_READY)) {
		dev_dbg(hw->dev, "spi not ready for tx?\n");
		complete(&hw->done);
		goto irq_done;
	}

438
439
	if (!s3c24xx_spi_usingfiq(hw)) {
		hw->count++;
440

441
442
		if (hw->rx)
			hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
443

444
445
446
447
448
449
450
451
452
453
454
455
		count++;

		if (count < hw->len)
			writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
		else
			complete(&hw->done);
	} else {
		hw->count = hw->len;
		hw->fiq_inuse = 0;

		if (hw->rx)
			hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT);
456
457

		complete(&hw->done);
458
	}
459
460
461
462
463

 irq_done:
	return IRQ_HANDLED;
}

464
465
466
467
468
469
470
471
472
473
474
static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
{
	/* for the moment, permanently enable the clock */

	clk_enable(hw->clk);

	/* program defaults into the registers */

	writeb(0xff, hw->regs + S3C2410_SPPRE);
	writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
	writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);
475

476
477
478
479
480
481
482
	if (hw->pdata) {
		if (hw->set_cs == s3c24xx_spi_gpiocs)
			gpio_direction_output(hw->pdata->pin_cs, 1);

		if (hw->pdata->gpio_setup)
			hw->pdata->gpio_setup(hw->pdata, 1);
	}
483
484
}

485
static int s3c24xx_spi_probe(struct platform_device *pdev)
486
{
487
	struct s3c2410_spi_info *pdata;
488
489
490
491
492
493
494
	struct s3c24xx_spi *hw;
	struct spi_master *master;
	int err = 0;

	master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
	if (master == NULL) {
		dev_err(&pdev->dev, "No memory for spi_master\n");
495
		return -ENOMEM;
496
497
498
499
	}

	hw = spi_master_get_devdata(master);

500
	hw->master = master;
Jingoo Han's avatar
Jingoo Han committed
501
	hw->pdata = pdata = dev_get_platdata(&pdev->dev);
502
503
	hw->dev = &pdev->dev;

504
	if (pdata == NULL) {
505
506
507
508
509
510
511
512
		dev_err(&pdev->dev, "No platform data supplied\n");
		err = -ENOENT;
		goto err_no_pdata;
	}

	platform_set_drvdata(pdev, hw);
	init_completion(&hw->done);

513
514
515
516
	/* initialise fiq handler */

	s3c24xx_spi_initfiq(hw);

517
518
	/* setup the master state. */

519
520
521
	/* the spi->mode bits understood by this driver: */
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;

522
	master->num_chipselect = hw->pdata->num_cs;
Ben Dooks's avatar
Ben Dooks committed
523
	master->bus_num = pdata->bus_num;
524
	master->bits_per_word_mask = SPI_BPW_MASK(8);
525

526
527
528
529
530
531
	/* setup the state for the bitbang driver */

	hw->bitbang.master         = hw->master;
	hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
	hw->bitbang.chipselect     = s3c24xx_spi_chipsel;
	hw->bitbang.txrx_bufs      = s3c24xx_spi_txrx;
532
533

	hw->master->setup  = s3c24xx_spi_setup;
534
535
536
537

	dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);

	/* find and map our resources */
538
	hw->regs = devm_platform_ioremap_resource(pdev, 0);
539
540
541
	if (IS_ERR(hw->regs)) {
		err = PTR_ERR(hw->regs);
		goto err_no_pdata;
542
543
544
545
546
	}

	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq < 0) {
		err = -ENOENT;
547
		goto err_no_pdata;
548
549
	}

550
551
	err = devm_request_irq(&pdev->dev, hw->irq, s3c24xx_spi_irq, 0,
				pdev->name, hw);
552
553
	if (err) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
554
		goto err_no_pdata;
555
556
	}

557
	hw->clk = devm_clk_get(&pdev->dev, "spi");
558
559
560
	if (IS_ERR(hw->clk)) {
		dev_err(&pdev->dev, "No clock for device\n");
		err = PTR_ERR(hw->clk);
561
		goto err_no_pdata;
562
563
564
565
	}

	/* setup any gpio we can */

566
	if (!pdata->set_cs) {
567
568
		if (pdata->pin_cs < 0) {
			dev_err(&pdev->dev, "No chipselect pin\n");
569
			err = -EINVAL;
570
571
			goto err_register;
		}
572

573
574
		err = devm_gpio_request(&pdev->dev, pdata->pin_cs,
					dev_name(&pdev->dev));
575
576
577
578
579
580
581
		if (err) {
			dev_err(&pdev->dev, "Failed to get gpio for cs\n");
			goto err_register;
		}

		hw->set_cs = s3c24xx_spi_gpiocs;
		gpio_direction_output(pdata->pin_cs, 1);
582
	} else
583
		hw->set_cs = pdata->set_cs;
584

585
586
	s3c24xx_spi_initialsetup(hw);

587
588
589
590
591
592
593
594
595
596
597
598
599
600
	/* register our spi controller */

	err = spi_bitbang_start(&hw->bitbang);
	if (err) {
		dev_err(&pdev->dev, "Failed to register SPI master\n");
		goto err_register;
	}

	return 0;

 err_register:
	clk_disable(hw->clk);

 err_no_pdata:
601
	spi_master_put(hw->master);
602
603
604
	return err;
}

605
static int s3c24xx_spi_remove(struct platform_device *dev)
606
607
608
{
	struct s3c24xx_spi *hw = platform_get_drvdata(dev);

609
	spi_bitbang_stop(&hw->bitbang);
610
611
612
613
614
615
616
617
	clk_disable(hw->clk);
	spi_master_put(hw->master);
	return 0;
}


#ifdef CONFIG_PM

Ben Dooks's avatar
Ben Dooks committed
618
static int s3c24xx_spi_suspend(struct device *dev)
619
{
620
	struct s3c24xx_spi *hw = dev_get_drvdata(dev);
621
622
623
624
625
	int ret;

	ret = spi_master_suspend(hw->master);
	if (ret)
		return ret;
626

627
628
629
	if (hw->pdata && hw->pdata->gpio_setup)
		hw->pdata->gpio_setup(hw->pdata, 0);

630
631
632
633
	clk_disable(hw->clk);
	return 0;
}

Ben Dooks's avatar
Ben Dooks committed
634
static int s3c24xx_spi_resume(struct device *dev)
635
{
636
	struct s3c24xx_spi *hw = dev_get_drvdata(dev);
637

638
	s3c24xx_spi_initialsetup(hw);
639
	return spi_master_resume(hw->master);
640
641
}

642
static const struct dev_pm_ops s3c24xx_spi_pmops = {
Ben Dooks's avatar
Ben Dooks committed
643
644
645
646
647
	.suspend	= s3c24xx_spi_suspend,
	.resume		= s3c24xx_spi_resume,
};

#define S3C24XX_SPI_PMOPS &s3c24xx_spi_pmops
648
#else
Ben Dooks's avatar
Ben Dooks committed
649
650
#define S3C24XX_SPI_PMOPS NULL
#endif /* CONFIG_PM */
651

652
MODULE_ALIAS("platform:s3c2410-spi");
Ben Dooks's avatar
Ben Dooks committed
653
static struct platform_driver s3c24xx_spi_driver = {
654
	.probe		= s3c24xx_spi_probe,
655
	.remove		= s3c24xx_spi_remove,
656
657
	.driver		= {
		.name	= "s3c2410-spi",
Ben Dooks's avatar
Ben Dooks committed
658
		.pm	= S3C24XX_SPI_PMOPS,
659
660
	},
};
661
module_platform_driver(s3c24xx_spi_driver);
662
663
664
665

MODULE_DESCRIPTION("S3C24XX SPI Driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");