xref: /linux/drivers/video/fbdev/mmp/hw/mmp_spi.c (revision 87c9c16317882dd6dbbc07e349bc3223e14f3244)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * linux/drivers/video/mmp/hw/mmp_spi.c
4  * using the spi in LCD controler for commands send
5  *
6  * Copyright (C) 2012 Marvell Technology Group Ltd.
7  * Authors:  Guoqing Li <ligq@marvell.com>
8  *          Lisa Du <cldu@marvell.com>
9  *          Zhou Zhu <zzhu3@marvell.com>
10  */
11 #include <linux/errno.h>
12 #include <linux/delay.h>
13 #include <linux/err.h>
14 #include <linux/io.h>
15 #include <linux/spi/spi.h>
16 #include "mmp_ctrl.h"
17 
18 /**
19  * spi_write - write command to the SPI port
20  * @spi:  the SPI device.
21  * @data: can be 8/16/32-bit, MSB justified data to write.
22  *
23  * Wait bus transfer complete IRQ.
24  * The caller is expected to perform the necessary locking.
25  *
26  * Returns:
27  *   %-ETIMEDOUT	timeout occurred
28  *   0			success
29  */
30 static inline int lcd_spi_write(struct spi_device *spi, u32 data)
31 {
32 	int timeout = 100000, isr, ret = 0;
33 	u32 tmp;
34 	void __iomem *reg_base = (void __iomem *)
35 		*(void **)spi_master_get_devdata(spi->master);
36 
37 	/* clear ISR */
38 	writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
39 
40 	switch (spi->bits_per_word) {
41 	case 8:
42 		writel_relaxed((u8)data, reg_base + LCD_SPU_SPI_TXDATA);
43 		break;
44 	case 16:
45 		writel_relaxed((u16)data, reg_base + LCD_SPU_SPI_TXDATA);
46 		break;
47 	case 32:
48 		writel_relaxed((u32)data, reg_base + LCD_SPU_SPI_TXDATA);
49 		break;
50 	default:
51 		dev_err(&spi->dev, "Wrong spi bit length\n");
52 	}
53 
54 	/* SPI start to send command */
55 	tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
56 	tmp &= ~CFG_SPI_START_MASK;
57 	tmp |= CFG_SPI_START(1);
58 	writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
59 
60 	isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
61 	while (!(isr & SPI_IRQ_ENA_MASK)) {
62 		udelay(100);
63 		isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
64 		if (!--timeout) {
65 			ret = -ETIMEDOUT;
66 			dev_err(&spi->dev, "spi cmd send time out\n");
67 			break;
68 		}
69 	}
70 
71 	tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
72 	tmp &= ~CFG_SPI_START_MASK;
73 	tmp |= CFG_SPI_START(0);
74 	writel_relaxed(tmp, reg_base + LCD_SPU_SPI_CTRL);
75 
76 	writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
77 
78 	return ret;
79 }
80 
81 static int lcd_spi_setup(struct spi_device *spi)
82 {
83 	void __iomem *reg_base = (void __iomem *)
84 		*(void **)spi_master_get_devdata(spi->master);
85 	u32 tmp;
86 
87 	tmp = CFG_SCLKCNT(16) |
88 		CFG_TXBITS(spi->bits_per_word) |
89 		CFG_SPI_SEL(1) | CFG_SPI_ENA(1) |
90 		CFG_SPI_3W4WB(1);
91 	writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
92 
93 	/*
94 	 * After set mode it need a time to pull up the spi singals,
95 	 * or it would cause the wrong waveform when send spi command,
96 	 * especially on pxa910h
97 	 */
98 	tmp = readl_relaxed(reg_base + SPU_IOPAD_CONTROL);
99 	if ((tmp & CFG_IOPADMODE_MASK) != IOPAD_DUMB18SPI)
100 		writel_relaxed(IOPAD_DUMB18SPI |
101 			(tmp & ~CFG_IOPADMODE_MASK),
102 			reg_base + SPU_IOPAD_CONTROL);
103 	udelay(20);
104 	return 0;
105 }
106 
107 static int lcd_spi_one_transfer(struct spi_device *spi, struct spi_message *m)
108 {
109 	struct spi_transfer *t;
110 	int i;
111 
112 	list_for_each_entry(t, &m->transfers, transfer_list) {
113 		switch (spi->bits_per_word) {
114 		case 8:
115 			for (i = 0; i < t->len; i++)
116 				lcd_spi_write(spi, ((u8 *)t->tx_buf)[i]);
117 			break;
118 		case 16:
119 			for (i = 0; i < t->len/2; i++)
120 				lcd_spi_write(spi, ((u16 *)t->tx_buf)[i]);
121 			break;
122 		case 32:
123 			for (i = 0; i < t->len/4; i++)
124 				lcd_spi_write(spi, ((u32 *)t->tx_buf)[i]);
125 			break;
126 		default:
127 			dev_err(&spi->dev, "Wrong spi bit length\n");
128 		}
129 	}
130 
131 	m->status = 0;
132 	if (m->complete)
133 		m->complete(m->context);
134 	return 0;
135 }
136 
137 int lcd_spi_register(struct mmphw_ctrl *ctrl)
138 {
139 	struct spi_master *master;
140 	void **p_regbase;
141 	int err;
142 
143 	master = spi_alloc_master(ctrl->dev, sizeof(void *));
144 	if (!master) {
145 		dev_err(ctrl->dev, "unable to allocate SPI master\n");
146 		return -ENOMEM;
147 	}
148 	p_regbase = spi_master_get_devdata(master);
149 	*p_regbase = (void __force *)ctrl->reg_base;
150 
151 	/* set bus num to 5 to avoid conflict with other spi hosts */
152 	master->bus_num = 5;
153 	master->num_chipselect = 1;
154 	master->setup = lcd_spi_setup;
155 	master->transfer = lcd_spi_one_transfer;
156 
157 	err = spi_register_master(master);
158 	if (err < 0) {
159 		dev_err(ctrl->dev, "unable to register SPI master\n");
160 		spi_master_put(master);
161 		return err;
162 	}
163 
164 	dev_info(&master->dev, "registered\n");
165 
166 	return 0;
167 }
168